Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
38afd6ad
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
38afd6ad
编写于
19年前
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
上级
8ed1383f
261688d0
无相关合并请求
变更
58
隐藏空白更改
内联
并排
Showing
58 changed file
with
687 addition
and
685 deletion
+687
-685
crypto/cipher.c
crypto/cipher.c
+3
-3
crypto/internal.h
crypto/internal.h
+1
-1
drivers/atm/ambassador.c
drivers/atm/ambassador.c
+3
-1
drivers/atm/firestream.c
drivers/atm/firestream.c
+4
-2
drivers/atm/he.c
drivers/atm/he.c
+0
-1
drivers/atm/idt77252.c
drivers/atm/idt77252.c
+2
-1
drivers/atm/zatm.c
drivers/atm/zatm.c
+61
-46
drivers/atm/zatm.h
drivers/atm/zatm.h
+1
-0
drivers/net/Kconfig
drivers/net/Kconfig
+17
-1
drivers/net/eql.c
drivers/net/eql.c
+8
-8
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/smc91c92_cs.c
+2
-1
drivers/net/wan/sdla_fr.c
drivers/net/wan/sdla_fr.c
+4
-3
drivers/net/wan/sdla_ft1.c
drivers/net/wan/sdla_ft1.c
+2
-1
drivers/net/wan/sdla_ppp.c
drivers/net/wan/sdla_ppp.c
+2
-1
drivers/net/wan/sdla_x25.c
drivers/net/wan/sdla_x25.c
+2
-1
drivers/net/wan/wanpipe_multppp.c
drivers/net/wan/wanpipe_multppp.c
+5
-4
drivers/usb/atm/speedtch.c
drivers/usb/atm/speedtch.c
+6
-6
include/linux/netfilter_ipv4/ip_conntrack.h
include/linux/netfilter_ipv4/ip_conntrack.h
+3
-0
include/linux/netfilter_ipv4/ip_conntrack_helper.h
include/linux/netfilter_ipv4/ip_conntrack_helper.h
+4
-3
include/linux/skbuff.h
include/linux/skbuff.h
+2
-1
include/linux/tc_ematch/tc_em_meta.h
include/linux/tc_ematch/tc_em_meta.h
+0
-5
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+2
-5
include/net/xfrm.h
include/net/xfrm.h
+1
-1
net/Kconfig
net/Kconfig
+0
-16
net/atm/Kconfig
net/atm/Kconfig
+2
-2
net/atm/svc.c
net/atm/svc.c
+0
-4
net/bridge/netfilter/Kconfig
net/bridge/netfilter/Kconfig
+1
-1
net/core/Makefile
net/core/Makefile
+2
-1
net/core/skbuff.c
net/core/skbuff.c
+2
-2
net/ipv4/Kconfig
net/ipv4/Kconfig
+3
-9
net/ipv4/af_inet.c
net/ipv4/af_inet.c
+1
-1
net/ipv4/fib_trie.c
net/ipv4/fib_trie.c
+387
-385
net/ipv4/ipip.c
net/ipv4/ipip.c
+32
-4
net/ipv4/netfilter/ip_conntrack_amanda.c
net/ipv4/netfilter/ip_conntrack_amanda.c
+3
-5
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_core.c
+21
-22
net/ipv4/netfilter/ip_conntrack_ftp.c
net/ipv4/netfilter/ip_conntrack_ftp.c
+7
-7
net/ipv4/netfilter/ip_conntrack_irc.c
net/ipv4/netfilter/ip_conntrack_irc.c
+3
-5
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_conntrack_standalone.c
+1
-1
net/ipv4/netfilter/ip_conntrack_tftp.c
net/ipv4/netfilter/ip_conntrack_tftp.c
+3
-5
net/ipv4/netfilter/ip_nat_amanda.c
net/ipv4/netfilter/ip_nat_amanda.c
+1
-3
net/ipv4/netfilter/ip_nat_ftp.c
net/ipv4/netfilter/ip_nat_ftp.c
+1
-3
net/ipv4/netfilter/ip_nat_irc.c
net/ipv4/netfilter/ip_nat_irc.c
+1
-3
net/ipv4/netfilter/ip_nat_proto_icmp.c
net/ipv4/netfilter/ip_nat_proto_icmp.c
+4
-3
net/ipv4/netfilter/ip_nat_proto_tcp.c
net/ipv4/netfilter/ip_nat_proto_tcp.c
+2
-1
net/ipv4/netfilter/ip_nat_proto_udp.c
net/ipv4/netfilter/ip_nat_proto_udp.c
+2
-1
net/ipv4/netfilter/ip_nat_tftp.c
net/ipv4/netfilter/ip_nat_tftp.c
+1
-3
net/ipv4/xfrm4_tunnel.c
net/ipv4/xfrm4_tunnel.c
+1
-2
net/ipv6/Kconfig
net/ipv6/Kconfig
+0
-1
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_tunnel.c
+33
-5
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_queue.c
+2
-0
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_LOG.c
+7
-4
net/netlink/af_netlink.c
net/netlink/af_netlink.c
+3
-2
net/sched/em_meta.c
net/sched/em_meta.c
+3
-43
net/sched/em_text.c
net/sched/em_text.c
+0
-3
net/sched/sch_generic.c
net/sched/sch_generic.c
+3
-4
net/sctp/input.c
net/sctp/input.c
+12
-33
net/sctp/ipv6.c
net/sctp/ipv6.c
+3
-4
net/sctp/objcnt.c
net/sctp/objcnt.c
+5
-1
未找到文件。
crypto/cipher.c
浏览文件 @
38afd6ad
...
...
@@ -41,7 +41,7 @@ static unsigned int crypt_slow(const struct cipher_desc *desc,
struct
scatter_walk
*
in
,
struct
scatter_walk
*
out
,
unsigned
int
bsize
)
{
unsigned
int
alignmask
=
crypto_tfm_alg_alignmask
(
desc
->
tfm
);
unsigned
long
alignmask
=
crypto_tfm_alg_alignmask
(
desc
->
tfm
);
u8
buffer
[
bsize
*
2
+
alignmask
];
u8
*
src
=
(
u8
*
)
ALIGN
((
unsigned
long
)
buffer
,
alignmask
+
1
);
u8
*
dst
=
src
+
bsize
;
...
...
@@ -160,7 +160,7 @@ static int crypt_iv_unaligned(struct cipher_desc *desc,
unsigned
int
nbytes
)
{
struct
crypto_tfm
*
tfm
=
desc
->
tfm
;
unsigned
int
alignmask
=
crypto_tfm_alg_alignmask
(
tfm
);
unsigned
long
alignmask
=
crypto_tfm_alg_alignmask
(
tfm
);
u8
*
iv
=
desc
->
info
;
if
(
unlikely
(((
unsigned
long
)
iv
&
alignmask
)))
{
...
...
@@ -424,7 +424,7 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm)
}
if
(
ops
->
cit_mode
==
CRYPTO_TFM_MODE_CBC
)
{
unsigned
int
align
;
unsigned
long
align
;
unsigned
long
addr
;
switch
(
crypto_tfm_alg_blocksize
(
tfm
))
{
...
...
This diff is collapsed.
Click to expand it.
crypto/internal.h
浏览文件 @
38afd6ad
...
...
@@ -75,7 +75,7 @@ static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg,
switch
(
flags
&
CRYPTO_TFM_MODE_MASK
)
{
case
CRYPTO_TFM_MODE_CBC
:
len
=
ALIGN
(
len
,
alg
->
cra_alignmask
+
1
);
len
=
ALIGN
(
len
,
(
unsigned
long
)
alg
->
cra_alignmask
+
1
);
len
+=
alg
->
cra_blocksize
;
break
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/atm/ambassador.c
浏览文件 @
38afd6ad
...
...
@@ -794,7 +794,9 @@ static void drain_rx_pools (amb_dev * dev) {
drain_rx_pool
(
dev
,
pool
);
}
static
inline
void
fill_rx_pool
(
amb_dev
*
dev
,
unsigned
char
pool
,
int
priority
)
{
static
inline
void
fill_rx_pool
(
amb_dev
*
dev
,
unsigned
char
pool
,
unsigned
int
__nocast
priority
)
{
rx_in
rx
;
amb_rxq
*
rxq
;
...
...
This diff is collapsed.
Click to expand it.
drivers/atm/firestream.c
浏览文件 @
38afd6ad
...
...
@@ -1374,7 +1374,8 @@ static void reset_chip (struct fs_dev *dev)
}
}
static
void
__devinit
*
aligned_kmalloc
(
int
size
,
int
flags
,
int
alignment
)
static
void
__devinit
*
aligned_kmalloc
(
int
size
,
unsigned
int
__nocast
flags
,
int
alignment
)
{
void
*
t
;
...
...
@@ -1464,7 +1465,8 @@ static inline int nr_buffers_in_freepool (struct fs_dev *dev, struct freepool *f
does. I've seen "receive abort: no buffers" and things started
working again after that... -- REW */
static
void
top_off_fp
(
struct
fs_dev
*
dev
,
struct
freepool
*
fp
,
int
gfp_flags
)
static
void
top_off_fp
(
struct
fs_dev
*
dev
,
struct
freepool
*
fp
,
unsigned
int
__nocast
gfp_flags
)
{
struct
FS_BPENTRY
*
qe
,
*
ne
;
struct
sk_buff
*
skb
;
...
...
This diff is collapsed.
Click to expand it.
drivers/atm/he.c
浏览文件 @
38afd6ad
...
...
@@ -57,7 +57,6 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/pci.h>
...
...
This diff is collapsed.
Click to expand it.
drivers/atm/idt77252.c
浏览文件 @
38afd6ad
...
...
@@ -46,6 +46,7 @@ static char const rcsid[] =
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <asm/uaccess.h>
...
...
@@ -780,7 +781,7 @@ push_on_scq(struct idt77252_dev *card, struct vc_map *vc, struct sk_buff *skb)
return
0
;
out:
if
(
jiffies
-
scq
->
trans_start
>
HZ
)
{
if
(
time_after
(
jiffies
,
scq
->
trans_start
+
HZ
)
)
{
printk
(
"%s: Error pushing TBD for %d.%d
\n
"
,
card
->
name
,
vc
->
tx_vcc
->
vpi
,
vc
->
tx_vcc
->
vci
);
#ifdef CONFIG_ATM_IDT77252_DEBUG
...
...
This diff is collapsed.
Click to expand it.
drivers/atm/zatm.c
浏览文件 @
38afd6ad
...
...
@@ -16,9 +16,9 @@
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/ioport.h>
/* for request_region */
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/atm_zatm.h>
#include <linux/capability.h>
#include <linux/bitops.h>
...
...
@@ -1257,22 +1257,22 @@ static int __init zatm_init(struct atm_dev *dev)
static
int
__init
zatm_start
(
struct
atm_dev
*
dev
)
{
struct
zatm_dev
*
zatm_dev
;
struct
zatm_dev
*
zatm_dev
=
ZATM_DEV
(
dev
);
struct
pci_dev
*
pdev
=
zatm_dev
->
pci_dev
;
unsigned
long
curr
;
int
pools
,
vccs
,
rx
;
int
error
,
i
,
ld
;
int
error
,
i
,
ld
;
DPRINTK
(
"zatm_start
\n
"
);
zatm_dev
=
ZATM_DEV
(
dev
);
zatm_dev
->
rx_map
=
zatm_dev
->
tx_map
=
NULL
;
for
(
i
=
0
;
i
<
NR_MBX
;
i
++
)
zatm_dev
->
mbx_start
[
i
]
=
0
;
if
(
request_irq
(
zatm_dev
->
irq
,
&
zatm_int
,
SA_SHIRQ
,
DEV_LABEL
,
dev
))
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): IRQ%d is already in use
\n
"
,
dev
->
number
,
zatm_dev
->
irq
);
return
-
EAGAIN
;
for
(
i
=
0
;
i
<
NR_MBX
;
i
++
)
zatm_dev
->
mbx_start
[
i
]
=
0
;
error
=
request_irq
(
zatm_dev
->
irq
,
zatm_int
,
SA_SHIRQ
,
DEV_LABEL
,
dev
);
if
(
error
<
0
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): IRQ%d is already in use
\n
"
,
dev
->
number
,
zatm_dev
->
irq
);
goto
done
;
}
request_region
(
zatm_dev
->
base
,
uPD98401_PORTS
,
DEV_LABEL
);
/* define memory regions */
pools
=
NR_POOLS
;
if
(
NR_SHAPERS
*
SHAPER_SIZE
>
pools
*
POOL_SIZE
)
...
...
@@ -1299,51 +1299,66 @@ static int __init zatm_start(struct atm_dev *dev)
"%ld VCs
\n
"
,
dev
->
number
,
NR_SHAPERS
,
pools
,
rx
,
(
zatm_dev
->
mem
-
curr
*
4
)
/
VC_SIZE
);
/* create mailboxes */
for
(
i
=
0
;
i
<
NR_MBX
;
i
++
)
if
(
mbx_entries
[
i
])
{
unsigned
long
here
;
here
=
(
unsigned
long
)
kmalloc
(
2
*
MBX_SIZE
(
i
),
GFP_KERNEL
);
if
(
!
here
)
{
error
=
-
ENOMEM
;
goto
out
;
}
if
((
here
^
(
here
+
MBX_SIZE
(
i
)))
&
~
0xffffUL
)
/* paranoia */
here
=
(
here
&
~
0xffffUL
)
+
0x10000
;
zatm_dev
->
mbx_start
[
i
]
=
here
;
if
((
here
^
virt_to_bus
((
void
*
)
here
))
&
0xffff
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): system "
"bus incompatible with driver
\n
"
,
dev
->
number
);
error
=
-
ENODEV
;
goto
out
;
}
DPRINTK
(
"mbx@0x%08lx-0x%08lx
\n
"
,
here
,
here
+
MBX_SIZE
(
i
));
zatm_dev
->
mbx_end
[
i
]
=
(
here
+
MBX_SIZE
(
i
))
&
0xffff
;
zout
(
virt_to_bus
((
void
*
)
here
)
>>
16
,
MSH
(
i
));
zout
(
virt_to_bus
((
void
*
)
here
),
MSL
(
i
));
zout
((
here
+
MBX_SIZE
(
i
))
&
0xffff
,
MBA
(
i
));
zout
(
here
&
0xffff
,
MTA
(
i
));
zout
(
here
&
0xffff
,
MWA
(
i
));
for
(
i
=
0
;
i
<
NR_MBX
;
i
++
)
{
void
*
mbx
;
dma_addr_t
mbx_dma
;
if
(
!
mbx_entries
[
i
])
continue
;
mbx
=
pci_alloc_consistent
(
pdev
,
2
*
MBX_SIZE
(
i
),
&
mbx_dma
);
if
(
!
mbx
)
{
error
=
-
ENOMEM
;
goto
out
;
}
/*
* Alignment provided by pci_alloc_consistent() isn't enough
* for this device.
*/
if
(((
unsigned
long
)
mbx
^
mbx_dma
)
&
0xffff
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): system "
"bus incompatible with driver
\n
"
,
dev
->
number
);
pci_free_consistent
(
pdev
,
2
*
MBX_SIZE
(
i
),
mbx
,
mbx_dma
);
error
=
-
ENODEV
;
goto
out
;
}
DPRINTK
(
"mbx@0x%08lx-0x%08lx
\n
"
,
mbx
,
mbx
+
MBX_SIZE
(
i
));
zatm_dev
->
mbx_start
[
i
]
=
(
unsigned
long
)
mbx
;
zatm_dev
->
mbx_dma
[
i
]
=
mbx_dma
;
zatm_dev
->
mbx_end
[
i
]
=
(
zatm_dev
->
mbx_start
[
i
]
+
MBX_SIZE
(
i
))
&
0xffff
;
zout
(
mbx_dma
>>
16
,
MSH
(
i
));
zout
(
mbx_dma
,
MSL
(
i
));
zout
(
zatm_dev
->
mbx_end
[
i
],
MBA
(
i
));
zout
((
unsigned
long
)
mbx
&
0xffff
,
MTA
(
i
));
zout
((
unsigned
long
)
mbx
&
0xffff
,
MWA
(
i
));
}
error
=
start_tx
(
dev
);
if
(
error
)
goto
out
;
if
(
error
)
goto
out
;
error
=
start_rx
(
dev
);
if
(
error
)
goto
out
;
if
(
error
)
goto
out_tx
;
error
=
dev
->
phy
->
start
(
dev
);
if
(
error
)
goto
out
;
if
(
error
)
goto
out_rx
;
zout
(
0xffffffff
,
IMR
);
/* enable interrupts */
/* enable TX & RX */
zout
(
zin
(
GMR
)
|
uPD98401_GMR_SE
|
uPD98401_GMR_RE
,
GMR
);
return
0
;
out:
for
(
i
=
0
;
i
<
NR_MBX
;
i
++
)
kfree
(
zatm_dev
->
mbx_start
[
i
]);
done:
return
error
;
out_rx:
kfree
(
zatm_dev
->
rx_map
);
out_tx:
kfree
(
zatm_dev
->
tx_map
);
out:
while
(
i
--
>
0
)
{
pci_free_consistent
(
pdev
,
2
*
MBX_SIZE
(
i
),
(
void
*
)
zatm_dev
->
mbx_start
[
i
],
zatm_dev
->
mbx_dma
[
i
]);
}
free_irq
(
zatm_dev
->
irq
,
dev
);
return
error
;
goto
done
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/atm/zatm.h
浏览文件 @
38afd6ad
...
...
@@ -73,6 +73,7 @@ struct zatm_dev {
int
chans
;
/* map size, must be 2^n */
/*-------------------------------- mailboxes */
unsigned
long
mbx_start
[
NR_MBX
];
/* start addresses */
dma_addr_t
mbx_dma
[
NR_MBX
];
u16
mbx_end
[
NR_MBX
];
/* end offset (in bytes) */
/*-------------------------------- other pointers */
u32
pool_base
;
/* Free buffer pool dsc (word addr) */
...
...
This diff is collapsed.
Click to expand it.
drivers/net/Kconfig
浏览文件 @
38afd6ad
...
...
@@ -2544,9 +2544,25 @@ config SHAPER
config NETCONSOLE
tristate "Network console logging support (EXPERIMENTAL)"
depends on NETDEVICES && EXPERIMENTAL
depends on NETDEVICES &&
INET &&
EXPERIMENTAL
---help---
If you want to log kernel messages over the network, enable this.
See <file:Documentation/networking/netconsole.txt> for details.
config NETPOLL
def_bool NETCONSOLE
config NETPOLL_RX
bool "Netpoll support for trapping incoming packets"
default n
depends on NETPOLL
config NETPOLL_TRAP
bool "Netpoll traffic trapping"
default n
depends on NETPOLL
config NET_POLL_CONTROLLER
def_bool NETPOLL
endmenu
This diff is collapsed.
Click to expand it.
drivers/net/eql.c
浏览文件 @
38afd6ad
...
...
@@ -132,7 +132,7 @@ static struct net_device_stats *eql_get_stats(struct net_device *dev);
#define eql_is_slave(dev) ((dev->flags & IFF_SLAVE) == IFF_SLAVE)
#define eql_is_master(dev) ((dev->flags & IFF_MASTER) == IFF_MASTER)
static
void
eql_kill_one_slave
(
slave_t
*
slave
);
static
void
eql_kill_one_slave
(
slave_
queue_t
*
queue
,
slave_
t
*
slave
);
static
void
eql_timer
(
unsigned
long
param
)
{
...
...
@@ -149,7 +149,7 @@ static void eql_timer(unsigned long param)
if
(
slave
->
bytes_queued
<
0
)
slave
->
bytes_queued
=
0
;
}
else
{
eql_kill_one_slave
(
slave
);
eql_kill_one_slave
(
&
eql
->
queue
,
slave
);
}
}
...
...
@@ -214,9 +214,10 @@ static int eql_open(struct net_device *dev)
return
0
;
}
static
void
eql_kill_one_slave
(
slave_t
*
slave
)
static
void
eql_kill_one_slave
(
slave_
queue_t
*
queue
,
slave_
t
*
slave
)
{
list_del
(
&
slave
->
list
);
queue
->
num_slaves
--
;
slave
->
dev
->
flags
&=
~
IFF_SLAVE
;
dev_put
(
slave
->
dev
);
kfree
(
slave
);
...
...
@@ -232,8 +233,7 @@ static void eql_kill_slave_queue(slave_queue_t *queue)
list_for_each_safe
(
this
,
tmp
,
head
)
{
slave_t
*
s
=
list_entry
(
this
,
slave_t
,
list
);
eql_kill_one_slave
(
s
);
queue
->
num_slaves
--
;
eql_kill_one_slave
(
queue
,
s
);
}
spin_unlock_bh
(
&
queue
->
lock
);
...
...
@@ -318,7 +318,7 @@ static slave_t *__eql_schedule_slaves(slave_queue_t *queue)
}
}
else
{
/* We found a dead slave, kill it. */
eql_kill_one_slave
(
slave
);
eql_kill_one_slave
(
queue
,
slave
);
}
}
return
best_slave
;
...
...
@@ -393,7 +393,7 @@ static int __eql_insert_slave(slave_queue_t *queue, slave_t *slave)
duplicate_slave
=
__eql_find_slave_dev
(
queue
,
slave
->
dev
);
if
(
duplicate_slave
!=
0
)
eql_kill_one_slave
(
duplicate_slave
);
eql_kill_one_slave
(
queue
,
duplicate_slave
);
list_add
(
&
slave
->
list
,
&
queue
->
all_slaves
);
queue
->
num_slaves
++
;
...
...
@@ -471,7 +471,7 @@ static int eql_emancipate(struct net_device *master_dev, slaving_request_t __use
slave_dev
);
if
(
slave
)
{
eql_kill_one_slave
(
slave
);
eql_kill_one_slave
(
&
eql
->
queue
,
slave
);
ret
=
0
;
}
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/pcmcia/smc91c92_cs.c
浏览文件 @
38afd6ad
...
...
@@ -41,6 +41,7 @@
#include <linux/ioport.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/jiffies.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
...
...
@@ -2092,7 +2093,7 @@ static void media_check(u_long arg)
}
/* Ignore collisions unless we've had no rx's recently */
if
(
jiffies
-
dev
->
last_rx
>
HZ
)
{
if
(
time_after
(
jiffies
,
dev
->
last_rx
+
HZ
)
)
{
if
(
smc
->
tx_err
||
(
smc
->
media_status
&
EPH_16COL
))
media
|=
EPH_16COL
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wan/sdla_fr.c
浏览文件 @
38afd6ad
...
...
@@ -152,6 +152,7 @@
#include <asm/io.h>
/* for inb(), outb(), etc. */
#include <linux/time.h>
/* for do_gettimeofday */
#include <linux/in.h>
/* sockaddr_in */
#include <linux/jiffies.h>
/* time_after() macro */
#include <asm/errno.h>
#include <linux/ip.h>
...
...
@@ -773,7 +774,7 @@ static int update(struct wan_device* wandev)
for
(;;)
{
if
(
card
->
u
.
f
.
update_comms_stats
==
0
)
break
;
if
(
(
jiffies
-
timeout
)
>
(
1
*
HZ
)){
if
(
time_after
(
jiffies
,
timeout
+
1
*
HZ
)){
card
->
u
.
f
.
update_comms_stats
=
0
;
return
-
EAGAIN
;
}
...
...
@@ -4799,7 +4800,7 @@ static void trigger_unconfig_fr(struct net_device *dev)
{
fr_channel_t
*
chan
=
dev
->
priv
;
volatile
sdla_t
*
card
=
chan
->
card
;
u
32
timeout
;
u
nsigned
long
timeout
;
fr508_flags_t
*
flags
=
card
->
flags
;
int
reset_critical
=
0
;
...
...
@@ -4821,7 +4822,7 @@ static void trigger_unconfig_fr(struct net_device *dev)
if
(
!
(
card
->
u
.
f
.
timer_int_enabled
&
TMR_INT_ENABLED_UNCONFIG
))
break
;
if
(
(
jiffies
-
timeout
)
>
(
1
*
HZ
)){
if
(
time_after
(
jiffies
,
timeout
+
1
*
HZ
)){
card
->
u
.
f
.
timer_int_enabled
&=
~
TMR_INT_ENABLED_UNCONFIG
;
printk
(
KERN_INFO
"%s: Failed to delete DLCI %i
\n
"
,
card
->
devname
,
chan
->
dlci
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wan/sdla_ft1.c
浏览文件 @
38afd6ad
...
...
@@ -29,6 +29,7 @@
#include <linux/wanrouter.h>
/* WAN router definitions */
#include <linux/wanpipe.h>
/* WANPIPE common user API definitions */
#include <linux/if_arp.h>
/* ARPHRD_* defines */
#include <linux/jiffies.h>
/* time_after() macro */
#include <linux/inetdevice.h>
#include <asm/uaccess.h>
...
...
@@ -164,7 +165,7 @@ int wpft1_init (sdla_t* card, wandev_conf_t* conf)
timeout
=
jiffies
;
while
(
mb
->
return_code
!=
'I'
)
/* Wait 1s for board to initialize */
if
(
(
jiffies
-
timeout
)
>
1
*
HZ
)
break
;
if
(
time_after
(
jiffies
,
timeout
+
1
*
HZ
)
)
break
;
if
(
mb
->
return_code
!=
'I'
)
{
printk
(
KERN_INFO
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wan/sdla_ppp.c
浏览文件 @
38afd6ad
...
...
@@ -101,6 +101,7 @@
#include <linux/if_arp.h>
/* ARPHRD_* defines */
#include <asm/byteorder.h>
/* htons(), etc. */
#include <linux/in.h>
/* sockaddr_in */
#include <linux/jiffies.h>
/* time_after() macro */
#include <asm/uaccess.h>
...
...
@@ -482,7 +483,7 @@ static int update(struct wan_device *wandev)
if
(
ppp_priv_area
->
update_comms_stats
==
0
){
break
;
}
if
(
(
jiffies
-
timeout
)
>
(
1
*
HZ
)){
if
(
time_after
(
jiffies
,
timeout
+
1
*
HZ
)){
ppp_priv_area
->
update_comms_stats
=
0
;
ppp_priv_area
->
timer_int_enabled
&=
~
TMR_INT_ENABLED_UPDATE
;
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wan/sdla_x25.c
浏览文件 @
38afd6ad
...
...
@@ -91,6 +91,7 @@
#include <linux/wanrouter.h>
/* WAN router definitions */
#include <linux/wanpipe.h>
/* WANPIPE common user API definitions */
#include <linux/workqueue.h>
#include <linux/jiffies.h>
/* time_after() macro */
#include <asm/byteorder.h>
/* htons(), etc. */
#include <asm/atomic.h>
#include <linux/delay.h>
/* Experimental delay */
...
...
@@ -867,7 +868,7 @@ static int update(struct wan_device* wandev)
if
(
!
(
card
->
u
.
x
.
timer_int_enabled
&
TMR_INT_ENABLED_UPDATE
)){
break
;
}
if
(
(
jiffies
-
timeout
)
>
1
*
HZ
){
if
(
time_after
(
jiffies
,
timeout
+
1
*
HZ
)
){
card
->
u
.
x
.
timer_int_enabled
&=
~
TMR_INT_ENABLED_UPDATE
;
return
-
EAGAIN
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/wan/wanpipe_multppp.c
浏览文件 @
38afd6ad
...
...
@@ -26,6 +26,7 @@
#include <linux/wanrouter.h>
/* WAN router definitions */
#include <linux/wanpipe.h>
/* WANPIPE common user API definitions */
#include <linux/if_arp.h>
/* ARPHRD_* defines */
#include <linux/jiffies.h>
/* time_after() macro */
#include <linux/in.h>
/* sockaddr_in */
#include <linux/inet.h>
...
...
@@ -270,9 +271,9 @@ int wsppp_init (sdla_t* card, wandev_conf_t* conf)
ready to accept commands. We expect this to be completed in less
than 1 second. */
timeout
=
jiffies
;
timeout
=
jiffies
+
1
*
HZ
;
while
(
mb
->
return_code
!=
'I'
)
/* Wait 1s for board to initialize */
if
(
(
jiffies
-
timeout
)
>
1
*
HZ
)
break
;
if
(
time_after
(
jiffies
,
timeout
)
)
break
;
if
(
mb
->
return_code
!=
'I'
)
{
printk
(
KERN_INFO
...
...
@@ -493,11 +494,11 @@ static int update(struct wan_device* wandev)
chdlc_priv_area
->
timer_int_enabled
=
TMR_INT_ENABLED_UPDATE
;
/* wait a maximum of 1 second for the statistics to be updated */
timeout
=
jiffies
;
timeout
=
jiffies
+
1
*
HZ
;
for
(;;)
{
if
(
chdlc_priv_area
->
update_comms_stats
==
0
)
break
;
if
(
(
jiffies
-
timeout
)
>
(
1
*
HZ
)){
if
(
time_after
(
jiffies
,
timeout
)){
chdlc_priv_area
->
update_comms_stats
=
0
;
chdlc_priv_area
->
timer_int_enabled
&=
~
TMR_INT_ENABLED_UPDATE
;
...
...
This diff is collapsed.
Click to expand it.
drivers/usb/atm/speedtch.c
浏览文件 @
38afd6ad
...
...
@@ -448,19 +448,19 @@ static void speedtch_check_status(struct speedtch_instance_data *instance)
case
0
:
atm_dev
->
signal
=
ATM_PHY_SIG_LOST
;
if
(
instance
->
last_status
)
atm_info
(
usbatm
,
"
ADSL line is down
\
n
"
);
atm_info
(
usbatm
,
"
%s
\n
"
,
"ADSL line is dow
n"
);
/* It may never resync again unless we ask it to... */
ret
=
speedtch_start_synchro
(
instance
);
break
;
case
0x08
:
atm_dev
->
signal
=
ATM_PHY_SIG_UNKNOWN
;
atm_info
(
usbatm
,
"
ADSL line is blocked?
\n
"
);
atm_info
(
usbatm
,
"
%s
\n
"
,
"ADSL line is blocked?
"
);
break
;
case
0x10
:
atm_dev
->
signal
=
ATM_PHY_SIG_LOST
;
atm_info
(
usbatm
,
"
ADSL line is synchronising
\n
"
);
atm_info
(
usbatm
,
"
%s
\n
"
,
"ADSL line is synchronising
"
);
break
;
case
0x20
:
...
...
@@ -502,7 +502,7 @@ static void speedtch_status_poll(unsigned long data)
if
(
instance
->
poll_delay
<
MAX_POLL_DELAY
)
mod_timer
(
&
instance
->
status_checker
.
timer
,
jiffies
+
msecs_to_jiffies
(
instance
->
poll_delay
));
else
atm_warn
(
instance
->
usbatm
,
"
Too many failures - disabling line status polling
\n
"
);
atm_warn
(
instance
->
usbatm
,
"
%s
\n
"
,
"Too many failures - disabling line status polling
"
);
}
static
void
speedtch_resubmit_int
(
unsigned
long
data
)
...
...
@@ -545,9 +545,9 @@ static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs)
if
((
count
==
6
)
&&
!
memcmp
(
up_int
,
instance
->
int_data
,
6
))
{
del_timer
(
&
instance
->
status_checker
.
timer
);
atm_info
(
usbatm
,
"
DSL line goes up
\n
"
);
atm_info
(
usbatm
,
"
%s
\n
"
,
"DSL line goes up
"
);
}
else
if
((
count
==
6
)
&&
!
memcmp
(
down_int
,
instance
->
int_data
,
6
))
{
atm_info
(
usbatm
,
"
DSL line goes down
\
n
"
);
atm_info
(
usbatm
,
"
%s
\n
"
,
"DSL line goes dow
n"
);
}
else
{
int
i
;
...
...
This diff is collapsed.
Click to expand it.
include/linux/netfilter_ipv4/ip_conntrack.h
浏览文件 @
38afd6ad
...
...
@@ -197,6 +197,9 @@ struct ip_conntrack_expect
/* Timer function; deletes the expectation. */
struct
timer_list
timeout
;
/* Usage count. */
atomic_t
use
;
#ifdef CONFIG_IP_NF_NAT_NEEDED
/* This is the original per-proto part, used to map the
* expected connection the way the recipient expects. */
...
...
This diff is collapsed.
Click to expand it.
include/linux/netfilter_ipv4/ip_conntrack_helper.h
浏览文件 @
38afd6ad
...
...
@@ -30,9 +30,10 @@ extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
extern
void
ip_conntrack_helper_unregister
(
struct
ip_conntrack_helper
*
);
/* Allocate space for an expectation: this is mandatory before calling
ip_conntrack_expect_related. */
extern
struct
ip_conntrack_expect
*
ip_conntrack_expect_alloc
(
void
);
extern
void
ip_conntrack_expect_free
(
struct
ip_conntrack_expect
*
exp
);
ip_conntrack_expect_related. You will have to call put afterwards. */
extern
struct
ip_conntrack_expect
*
ip_conntrack_expect_alloc
(
struct
ip_conntrack
*
master
);
extern
void
ip_conntrack_expect_put
(
struct
ip_conntrack_expect
*
exp
);
/* Add an expected connection: can have more than one per connection */
extern
int
ip_conntrack_expect_related
(
struct
ip_conntrack_expect
*
exp
);
...
...
This diff is collapsed.
Click to expand it.
include/linux/skbuff.h
浏览文件 @
38afd6ad
...
...
@@ -502,7 +502,8 @@ static inline struct sk_buff *skb_share_check(struct sk_buff *skb,
*
* %NULL is returned on a memory allocation failure.
*/
static
inline
struct
sk_buff
*
skb_unshare
(
struct
sk_buff
*
skb
,
int
pri
)
static
inline
struct
sk_buff
*
skb_unshare
(
struct
sk_buff
*
skb
,
unsigned
int
__nocast
pri
)
{
might_sleep_if
(
pri
&
__GFP_WAIT
);
if
(
skb_cloned
(
skb
))
{
...
...
This diff is collapsed.
Click to expand it.
include/linux/tc_ematch/tc_em_meta.h
浏览文件 @
38afd6ad
...
...
@@ -41,19 +41,14 @@ enum
TCF_META_ID_LOADAVG_1
,
TCF_META_ID_LOADAVG_2
,
TCF_META_ID_DEV
,
TCF_META_ID_INDEV
,
TCF_META_ID_REALDEV
,
TCF_META_ID_PRIORITY
,
TCF_META_ID_PROTOCOL
,
TCF_META_ID_SECURITY
,
/* obsolete */
TCF_META_ID_PKTTYPE
,
TCF_META_ID_PKTLEN
,
TCF_META_ID_DATALEN
,
TCF_META_ID_MACLEN
,
TCF_META_ID_NFMARK
,
TCF_META_ID_TCINDEX
,
TCF_META_ID_TCVERDICT
,
TCF_META_ID_TCCLASSID
,
TCF_META_ID_RTCLASSID
,
TCF_META_ID_RTIIF
,
TCF_META_ID_SK_FAMILY
,
...
...
This diff is collapsed.
Click to expand it.
include/net/sctp/sctp.h
浏览文件 @
38afd6ad
...
...
@@ -167,15 +167,12 @@ void sctp_unhash_established(struct sctp_association *);
void
sctp_hash_endpoint
(
struct
sctp_endpoint
*
);
void
sctp_unhash_endpoint
(
struct
sctp_endpoint
*
);
struct
sock
*
sctp_err_lookup
(
int
family
,
struct
sk_buff
*
,
struct
sctphdr
*
,
struct
sctp_endpoint
**
,
struct
sctp_association
**
,
struct
sctphdr
*
,
struct
sctp_association
**
,
struct
sctp_transport
**
);
void
sctp_err_finish
(
struct
sock
*
,
struct
sctp_endpoint
*
,
struct
sctp_association
*
);
void
sctp_err_finish
(
struct
sock
*
,
struct
sctp_association
*
);
void
sctp_icmp_frag_needed
(
struct
sock
*
,
struct
sctp_association
*
,
struct
sctp_transport
*
t
,
__u32
pmtu
);
void
sctp_icmp_proto_unreachable
(
struct
sock
*
sk
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
t
);
...
...
This diff is collapsed.
Click to expand it.
include/net/xfrm.h
浏览文件 @
38afd6ad
...
...
@@ -803,7 +803,7 @@ struct xfrm_algo_desc {
/* XFRM tunnel handlers. */
struct
xfrm_tunnel
{
int
(
*
handler
)(
struct
sk_buff
*
skb
);
void
(
*
err_handler
)(
struct
sk_buff
*
skb
,
void
*
info
);
void
(
*
err_handler
)(
struct
sk_buff
*
skb
,
__u32
info
);
};
struct
xfrm6_tunnel
{
...
...
This diff is collapsed.
Click to expand it.
net/Kconfig
浏览文件 @
38afd6ad
...
...
@@ -209,22 +209,6 @@ endmenu
endmenu
config NETPOLL
def_bool NETCONSOLE
config NETPOLL_RX
bool "Netpoll support for trapping incoming packets"
default n
depends on NETPOLL
config NETPOLL_TRAP
bool "Netpoll traffic trapping"
default n
depends on NETPOLL
config NET_POLL_CONTROLLER
def_bool NETPOLL
source "net/ax25/Kconfig"
source "net/irda/Kconfig"
source "net/bluetooth/Kconfig"
...
...
This diff is collapsed.
Click to expand it.
net/atm/Kconfig
浏览文件 @
38afd6ad
...
...
@@ -60,7 +60,7 @@ config ATM_BR2684
tristate "RFC1483/2684 Bridged protocols"
depends on ATM && INET
help
ATM PVCs can carry ethernet PDUs according to
rfc
2684 (formerly 1483)
ATM PVCs can carry ethernet PDUs according to
RFC
2684 (formerly 1483)
This device will act like an ethernet from the kernels point of view,
with the traffic being carried by ATM PVCs (currently 1 PVC/device).
This is sometimes used over DSL lines. If in doubt, say N.
...
...
@@ -69,6 +69,6 @@ config ATM_BR2684_IPFILTER
bool "Per-VC IP filter kludge"
depends on ATM_BR2684
help
This is an experimental mechanism for users who need to terminat
ing
a
This is an experimental mechanism for users who need to terminat
e
a
large number of IP-only vcc's. Do not enable this unless you are sure
you know what you are doing.
This diff is collapsed.
Click to expand it.
net/atm/svc.c
浏览文件 @
38afd6ad
...
...
@@ -118,10 +118,6 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
goto
out
;
}
vcc
=
ATM_SD
(
sock
);
if
(
test_bit
(
ATM_VF_SESSION
,
&
vcc
->
flags
))
{
error
=
-
EINVAL
;
goto
out
;
}
addr
=
(
struct
sockaddr_atmsvc
*
)
sockaddr
;
if
(
addr
->
sas_family
!=
AF_ATMSVC
)
{
error
=
-
EAFNOSUPPORT
;
...
...
This diff is collapsed.
Click to expand it.
net/bridge/netfilter/Kconfig
浏览文件 @
38afd6ad
...
...
@@ -138,7 +138,7 @@ config BRIDGE_EBT_VLAN
#
config BRIDGE_EBT_ARPREPLY
tristate "ebt: arp reply target support"
depends on BRIDGE_NF_EBTABLES
depends on BRIDGE_NF_EBTABLES
&& INET
help
This option adds the arp reply target, which allows
automatically sending arp replies to arp requests.
...
...
This diff is collapsed.
Click to expand it.
net/core/Makefile
浏览文件 @
38afd6ad
...
...
@@ -7,9 +7,10 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
obj-$(CONFIG_SYSCTL)
+=
sysctl_net_core.o
obj-y
+=
flow.o
dev.o ethtool.o dev_mcast.o dst.o
\
obj-y
+=
dev.o ethtool.o dev_mcast.o dst.o
\
neighbour.o rtnetlink.o utils.o link_watch.o filter.o
obj-$(CONFIG_XFRM)
+=
flow.o
obj-$(CONFIG_SYSFS)
+=
net-sysfs.o
obj-$(CONFIG_NETFILTER)
+=
netfilter.o
obj-$(CONFIG_NET_DIVERT)
+=
dv.o
...
...
This diff is collapsed.
Click to expand it.
net/core/skbuff.c
浏览文件 @
38afd6ad
...
...
@@ -377,8 +377,8 @@ struct sk_buff *skb_clone(struct sk_buff *skb, unsigned int __nocast gfp_mask)
C
(
tc_index
);
#ifdef CONFIG_NET_CLS_ACT
n
->
tc_verd
=
SET_TC_VERD
(
skb
->
tc_verd
,
0
);
n
->
tc_verd
=
CLR_TC_OK2MUNGE
(
skb
->
tc_verd
);
n
->
tc_verd
=
CLR_TC_MUNGED
(
skb
->
tc_verd
);
n
->
tc_verd
=
CLR_TC_OK2MUNGE
(
n
->
tc_verd
);
n
->
tc_verd
=
CLR_TC_MUNGED
(
n
->
tc_verd
);
C
(
input_dev
);
C
(
tc_classid
);
#endif
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/Kconfig
浏览文件 @
38afd6ad
...
...
@@ -54,9 +54,9 @@ config IP_ADVANCED_ROUTER
choice
prompt "Choose IP: FIB lookup algorithm (choose FIB_HASH if unsure)"
depends on IP_ADVANCED_ROUTER
default IP_FIB_HASH
default
ASK_
IP_FIB_HASH
config IP_FIB_HASH
config
ASK_
IP_FIB_HASH
bool "FIB_HASH"
---help---
Current FIB is very proven and good enough for most users.
...
...
@@ -82,12 +82,8 @@ config IP_FIB_TRIE
endchoice
# If the user does not enable advanced routing, he gets the safe
# default of the fib-hash algorithm.
config IP_FIB_HASH
bool
depends on !IP_ADVANCED_ROUTER
default y
def_bool ASK_IP_FIB_HASH || !IP_ADVANCED_ROUTER
config IP_MULTIPLE_TABLES
bool "IP: policy routing"
...
...
@@ -239,7 +235,6 @@ config IP_PNP_RARP
# bool ' IP: ARP support' CONFIG_IP_PNP_ARP
config NET_IPIP
tristate "IP: tunneling"
select INET_TUNNEL
---help---
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
...
...
@@ -256,7 +251,6 @@ config NET_IPIP
config NET_IPGRE
tristate "IP: GRE tunnels over IP"
select XFRM
help
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/af_inet.c
浏览文件 @
38afd6ad
...
...
@@ -1157,7 +1157,7 @@ static int __init ipv4_proc_init(void)
#ifdef CONFIG_IP_FIB_TRIE
if
(
fib_stat_proc_init
())
goto
out_fib_stat
;
#endif
#endif
if
(
ip_misc_proc_init
())
goto
out_misc
;
out:
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/fib_trie.c
浏览文件 @
38afd6ad
...
...
@@ -90,14 +90,14 @@ typedef unsigned int t_key;
#define T_LEAF 1
#define NODE_TYPE_MASK 0x1UL
#define NODE_PARENT(_node) \
((struct tnode *)((_node)->_parent & ~NODE_TYPE_MASK))
((struct tnode *)((_node)->_parent & ~NODE_TYPE_MASK))
#define NODE_SET_PARENT(_node, _ptr) \
((_node)->_parent = (((unsigned long)(_ptr)) | \
((_node)->_parent = (((unsigned long)(_ptr)) | \
((_node)->_parent & NODE_TYPE_MASK)))
#define NODE_INIT_PARENT(_node, _type) \
((_node)->_parent = (_type))
((_node)->_parent = (_type))
#define NODE_TYPE(_node) \
((_node)->_parent & NODE_TYPE_MASK)
((_node)->_parent & NODE_TYPE_MASK)
#define IS_TNODE(n) (!(n->_parent & T_LEAF))
#define IS_LEAF(n) (n->_parent & T_LEAF)
...
...
@@ -147,7 +147,7 @@ struct trie_stat {
unsigned
int
leaves
;
unsigned
int
nullpointers
;
unsigned
int
nodesizes
[
MAX_CHILDS
];
};
};
struct
trie
{
struct
node
*
trie
;
...
...
@@ -185,9 +185,9 @@ static void trie_bug(char *err)
BUG
();
}
static
inline
struct
node
*
tnode_get_child
(
struct
tnode
*
tn
,
int
i
)
static
inline
struct
node
*
tnode_get_child
(
struct
tnode
*
tn
,
int
i
)
{
if
(
i
>=
1
<<
tn
->
bits
)
if
(
i
>=
1
<<
tn
->
bits
)
trie_bug
(
"tnode_get_child"
);
return
tn
->
child
[
i
];
...
...
@@ -202,7 +202,7 @@ static inline int tnode_child_length(struct tnode *tn)
_________________________________________________________________
| i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C |
----------------------------------------------------------------
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
_________________________________________________________________
| C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u |
...
...
@@ -226,25 +226,25 @@ static inline t_key tkey_extract_bits(t_key a, int offset, int bits)
static
inline
int
tkey_equals
(
t_key
a
,
t_key
b
)
{
return
a
==
b
;
return
a
==
b
;
}
static
inline
int
tkey_sub_equals
(
t_key
a
,
int
offset
,
int
bits
,
t_key
b
)
{
if
(
bits
==
0
||
offset
>=
KEYLENGTH
)
return
1
;
if
(
bits
==
0
||
offset
>=
KEYLENGTH
)
return
1
;
bits
=
bits
>
KEYLENGTH
?
KEYLENGTH
:
bits
;
return
((
a
^
b
)
<<
offset
)
>>
(
KEYLENGTH
-
bits
)
==
0
;
}
}
static
inline
int
tkey_mismatch
(
t_key
a
,
int
offset
,
t_key
b
)
{
t_key
diff
=
a
^
b
;
int
i
=
offset
;
if
(
!
diff
)
return
0
;
while
((
diff
<<
i
)
>>
(
KEYLENGTH
-
1
)
==
0
)
if
(
!
diff
)
return
0
;
while
((
diff
<<
i
)
>>
(
KEYLENGTH
-
1
)
==
0
)
i
++
;
return
i
;
}
...
...
@@ -314,6 +314,7 @@ static void fn_free_alias(struct fib_alias *fa)
The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into
n's child array, and will of course be different for each child.
The rest of the bits, from (n->pos + n->bits) onward, are completely unknown
at this point.
...
...
@@ -321,7 +322,7 @@ static void fn_free_alias(struct fib_alias *fa)
static
void
check_tnode
(
struct
tnode
*
tn
)
{
if
(
tn
&&
tn
->
pos
+
tn
->
bits
>
32
)
{
if
(
tn
&&
tn
->
pos
+
tn
->
bits
>
32
)
{
printk
(
"TNODE ERROR tn=%p, pos=%d, bits=%d
\n
"
,
tn
,
tn
->
pos
,
tn
->
bits
);
}
}
...
...
@@ -332,7 +333,7 @@ static int inflate_threshold = 50;
static
struct
leaf
*
leaf_new
(
void
)
{
struct
leaf
*
l
=
kmalloc
(
sizeof
(
struct
leaf
),
GFP_KERNEL
);
if
(
l
)
{
if
(
l
)
{
NODE_INIT_PARENT
(
l
,
T_LEAF
);
INIT_HLIST_HEAD
(
&
l
->
list
);
}
...
...
@@ -342,7 +343,7 @@ static struct leaf *leaf_new(void)
static
struct
leaf_info
*
leaf_info_new
(
int
plen
)
{
struct
leaf_info
*
li
=
kmalloc
(
sizeof
(
struct
leaf_info
),
GFP_KERNEL
);
if
(
li
)
{
if
(
li
)
{
li
->
plen
=
plen
;
INIT_LIST_HEAD
(
&
li
->
falh
);
}
...
...
@@ -365,7 +366,7 @@ static struct tnode *tnode_alloc(unsigned int size)
return
kmalloc
(
size
,
GFP_KERNEL
);
}
else
{
return
(
struct
tnode
*
)
__get_free_pages
(
GFP_KERNEL
,
get_order
(
size
));
__get_free_pages
(
GFP_KERNEL
,
get_order
(
size
));
}
}
...
...
@@ -386,7 +387,7 @@ static struct tnode* tnode_new(t_key key, int pos, int bits)
int
sz
=
sizeof
(
struct
tnode
)
+
nchildren
*
sizeof
(
struct
node
*
);
struct
tnode
*
tn
=
tnode_alloc
(
sz
);
if
(
tn
)
{
if
(
tn
)
{
memset
(
tn
,
0
,
sz
);
NODE_INIT_PARENT
(
tn
,
T_TNODE
);
tn
->
pos
=
pos
;
...
...
@@ -395,7 +396,8 @@ static struct tnode* tnode_new(t_key key, int pos, int bits)
tn
->
full_children
=
0
;
tn
->
empty_children
=
1
<<
bits
;
}
if
(
trie_debug
>
0
)
if
(
trie_debug
>
0
)
printk
(
"AT %p s=%u %u
\n
"
,
tn
,
(
unsigned
int
)
sizeof
(
struct
tnode
),
(
unsigned
int
)
(
sizeof
(
struct
node
)
*
1
<<
bits
));
return
tn
;
...
...
@@ -403,17 +405,17 @@ static struct tnode* tnode_new(t_key key, int pos, int bits)
static
void
tnode_free
(
struct
tnode
*
tn
)
{
if
(
!
tn
)
{
if
(
!
tn
)
{
trie_bug
(
"tnode_free
\n
"
);
}
if
(
IS_LEAF
(
tn
))
{
if
(
IS_LEAF
(
tn
))
{
free_leaf
((
struct
leaf
*
)
tn
);
if
(
trie_debug
>
0
)
if
(
trie_debug
>
0
)
printk
(
"FL %p
\n
"
,
tn
);
}
else
if
(
IS_TNODE
(
tn
))
{
else
if
(
IS_TNODE
(
tn
))
{
__tnode_free
(
tn
);
if
(
trie_debug
>
0
)
if
(
trie_debug
>
0
)
printk
(
"FT %p
\n
"
,
tn
);
}
else
{
...
...
@@ -428,58 +430,58 @@ static void tnode_free(struct tnode *tn)
static
inline
int
tnode_full
(
struct
tnode
*
tn
,
struct
node
*
n
)
{
if
(
n
==
NULL
||
IS_LEAF
(
n
))
if
(
n
==
NULL
||
IS_LEAF
(
n
))
return
0
;
return
((
struct
tnode
*
)
n
)
->
pos
==
tn
->
pos
+
tn
->
bits
;
}
static
inline
void
put_child
(
struct
trie
*
t
,
struct
tnode
*
tn
,
int
i
,
struct
node
*
n
)
static
inline
void
put_child
(
struct
trie
*
t
,
struct
tnode
*
tn
,
int
i
,
struct
node
*
n
)
{
tnode_put_child_reorg
(
tn
,
i
,
n
,
-
1
);
}
/*
/*
* Add a child at position i overwriting the old value.
* Update the value of full_children and empty_children.
*/
static
void
tnode_put_child_reorg
(
struct
tnode
*
tn
,
int
i
,
struct
node
*
n
,
int
wasfull
)
static
void
tnode_put_child_reorg
(
struct
tnode
*
tn
,
int
i
,
struct
node
*
n
,
int
wasfull
)
{
struct
node
*
chi
;
int
isfull
;
if
(
i
>=
1
<<
tn
->
bits
)
{
if
(
i
>=
1
<<
tn
->
bits
)
{
printk
(
"bits=%d, i=%d
\n
"
,
tn
->
bits
,
i
);
trie_bug
(
"tnode_put_child_reorg bits"
);
}
write_lock_bh
(
&
fib_lock
);
chi
=
tn
->
child
[
i
];
chi
=
tn
->
child
[
i
];
/* update emptyChildren */
if
(
n
==
NULL
&&
chi
!=
NULL
)
tn
->
empty_children
++
;
else
if
(
n
!=
NULL
&&
chi
==
NULL
)
tn
->
empty_children
--
;
/* update fullChildren */
if
(
wasfull
==
-
1
)
wasfull
=
tnode_full
(
tn
,
chi
);
isfull
=
tnode_full
(
tn
,
n
);
if
(
wasfull
&&
!
isfull
)
if
(
wasfull
&&
!
isfull
)
tn
->
full_children
--
;
else
if
(
!
wasfull
&&
isfull
)
else
if
(
!
wasfull
&&
isfull
)
tn
->
full_children
++
;
if
(
n
)
NODE_SET_PARENT
(
n
,
tn
);
if
(
n
)
NODE_SET_PARENT
(
n
,
tn
);
tn
->
child
[
i
]
=
n
;
write_unlock_bh
(
&
fib_lock
);
}
static
struct
node
*
resize
(
struct
trie
*
t
,
struct
tnode
*
tn
)
static
struct
node
*
resize
(
struct
trie
*
t
,
struct
tnode
*
tn
)
{
int
i
;
int
err
=
0
;
...
...
@@ -487,8 +489,8 @@ static struct node *resize(struct trie *t, struct tnode *tn)
if
(
!
tn
)
return
NULL
;
if
(
trie_debug
)
printk
(
"In tnode_resize %p inflate_threshold=%d threshold=%d
\n
"
,
if
(
trie_debug
)
printk
(
"In tnode_resize %p inflate_threshold=%d threshold=%d
\n
"
,
tn
,
inflate_threshold
,
halve_threshold
);
/* No children */
...
...
@@ -505,7 +507,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
/* compress one level */
struct
node
*
n
=
tn
->
child
[
i
];
if
(
n
)
if
(
n
)
NODE_INIT_PARENT
(
n
,
NODE_TYPE
(
n
));
write_unlock_bh
(
&
fib_lock
);
...
...
@@ -514,72 +516,72 @@ static struct node *resize(struct trie *t, struct tnode *tn)
}
write_unlock_bh
(
&
fib_lock
);
}
/*
/*
* Double as long as the resulting node has a number of
* nonempty nodes that are above the threshold.
*/
/*
* From "Implementing a dynamic compressed trie" by Stefan Nilsson of
* the Helsinki University of Technology and Matti Tikkanen of Nokia
* From "Implementing a dynamic compressed trie" by Stefan Nilsson of
* the Helsinki University of Technology and Matti Tikkanen of Nokia
* Telecommunications, page 6:
* "A node is doubled if the ratio of non-empty children to all
* "A node is doubled if the ratio of non-empty children to all
* children in the *doubled* node is at least 'high'."
*
* 'high' in this instance is the variable 'inflate_threshold'. It
* is expressed as a percentage, so we multiply it with
* tnode_child_length() and instead of multiplying by 2 (since the
* child array will be doubled by inflate()) and multiplying
* the left-hand side by 100 (to handle the percentage thing) we
* 'high' in this instance is the variable 'inflate_threshold'. It
* is expressed as a percentage, so we multiply it with
* tnode_child_length() and instead of multiplying by 2 (since the
* child array will be doubled by inflate()) and multiplying
* the left-hand side by 100 (to handle the percentage thing) we
* multiply the left-hand side by 50.
*
* The left-hand side may look a bit weird: tnode_child_length(tn)
* - tn->empty_children is of course the number of non-null children
* in the current node. tn->full_children is the number of "full"
*
* The left-hand side may look a bit weird: tnode_child_length(tn)
* - tn->empty_children is of course the number of non-null children
* in the current node. tn->full_children is the number of "full"
* children, that is non-null tnodes with a skip value of 0.
* All of those will be doubled in the resulting inflated tnode, so
* All of those will be doubled in the resulting inflated tnode, so
* we just count them one extra time here.
*
*
* A clearer way to write this would be:
*
*
* to_be_doubled = tn->full_children;
* not_to_be_doubled = tnode_child_length(tn) - tn->empty_children -
* not_to_be_doubled = tnode_child_length(tn) - tn->empty_children -
* tn->full_children;
*
* new_child_length = tnode_child_length(tn) * 2;
*
* new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) /
* new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) /
* new_child_length;
* if (new_fill_factor >= inflate_threshold)
*
* ...and so on, tho it would mess up the while() loop.
*
*
* ...and so on, tho it would mess up the while
() loop.
*
* anyway,
* 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >=
* inflate_threshold
*
*
* avoid a division:
* 100 * (not_to_be_doubled + 2*to_be_doubled) >=
* inflate_threshold * new_child_length
*
*
* expand not_to_be_doubled and to_be_doubled, and shorten:
* 100 * (tnode_child_length(tn) - tn->empty_children +
* 100 * (tnode_child_length(tn) - tn->empty_children +
* tn->full_children ) >= inflate_threshold * new_child_length
*
*
* expand new_child_length:
* 100 * (tnode_child_length(tn) - tn->empty_children +
* 100 * (tnode_child_length(tn) - tn->empty_children +
* tn->full_children ) >=
* inflate_threshold * tnode_child_length(tn) * 2
*
*
* shorten again:
* 50 * (tn->full_children + tnode_child_length(tn) -
* tn->empty_children ) >= inflate_threshold *
* 50 * (tn->full_children + tnode_child_length(tn) -
* tn->empty_children ) >= inflate_threshold *
* tnode_child_length(tn)
*
*
*/
check_tnode
(
tn
);
err
=
0
;
while
((
tn
->
full_children
>
0
&&
50
*
(
tn
->
full_children
+
tnode_child_length
(
tn
)
-
tn
->
empty_children
)
>=
...
...
@@ -587,7 +589,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
tn
=
inflate
(
t
,
tn
,
&
err
);
if
(
err
)
{
if
(
err
)
{
#ifdef CONFIG_IP_FIB_TRIE_STATS
t
->
stats
.
resize_node_skipped
++
;
#endif
...
...
@@ -609,7 +611,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
tn
=
halve
(
t
,
tn
,
&
err
);
if
(
err
)
{
if
(
err
)
{
#ifdef CONFIG_IP_FIB_TRIE_STATS
t
->
stats
.
resize_node_skipped
++
;
#endif
...
...
@@ -617,18 +619,18 @@ static struct node *resize(struct trie *t, struct tnode *tn)
}
}
/* Only one child remains */
if
(
tn
->
empty_children
==
tnode_child_length
(
tn
)
-
1
)
for
(
i
=
0
;
i
<
tnode_child_length
(
tn
);
i
++
)
{
write_lock_bh
(
&
fib_lock
);
if
(
tn
->
child
[
i
]
!=
NULL
)
{
/* compress one level */
struct
node
*
n
=
tn
->
child
[
i
];
if
(
n
)
if
(
n
)
NODE_INIT_PARENT
(
n
,
NODE_TYPE
(
n
));
write_unlock_bh
(
&
fib_lock
);
...
...
@@ -648,7 +650,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
int
olen
=
tnode_child_length
(
tn
);
int
i
;
if
(
trie_debug
)
if
(
trie_debug
)
printk
(
"In inflate
\n
"
);
tn
=
tnode_new
(
oldtnode
->
key
,
oldtnode
->
pos
,
oldtnode
->
bits
+
1
);
...
...
@@ -659,12 +661,12 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
}
/*
* Preallocate and store tnodes before the actual work so we
* don't get into an inconsistent state if memory allocation
* fails. In case of failure we return the oldnode and inflate
* Preallocate and store tnodes before the actual work so we
* don't get into an inconsistent state if memory allocation
* fails. In case of failure we return the oldnode and inflate
* of tnode is ignored.
*/
for
(
i
=
0
;
i
<
olen
;
i
++
)
{
struct
tnode
*
inode
=
(
struct
tnode
*
)
tnode_get_child
(
oldtnode
,
i
);
...
...
@@ -675,20 +677,20 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
struct
tnode
*
left
,
*
right
;
t_key
m
=
TKEY_GET_MASK
(
inode
->
pos
,
1
);
left
=
tnode_new
(
inode
->
key
&
(
~
m
),
inode
->
pos
+
1
,
inode
->
bits
-
1
);
if
(
!
left
)
{
*
err
=
-
ENOMEM
;
if
(
!
left
)
{
*
err
=
-
ENOMEM
;
break
;
}
right
=
tnode_new
(
inode
->
key
|
m
,
inode
->
pos
+
1
,
inode
->
bits
-
1
);
if
(
!
right
)
{
*
err
=
-
ENOMEM
;
if
(
!
right
)
{
*
err
=
-
ENOMEM
;
break
;
}
...
...
@@ -697,32 +699,32 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
}
}
if
(
*
err
)
{
if
(
*
err
)
{
int
size
=
tnode_child_length
(
tn
);
int
j
;
for
(
j
=
0
;
j
<
size
;
j
++
)
if
(
tn
->
child
[
j
])
for
(
j
=
0
;
j
<
size
;
j
++
)
if
(
tn
->
child
[
j
])
tnode_free
((
struct
tnode
*
)
tn
->
child
[
j
]);
tnode_free
(
tn
);
*
err
=
-
ENOMEM
;
return
oldtnode
;
}
for
(
i
=
0
;
i
<
olen
;
i
++
)
{
struct
node
*
node
=
tnode_get_child
(
oldtnode
,
i
);
/* An empty child */
if
(
node
==
NULL
)
continue
;
/* A leaf or an internal node with skipped bits */
if
(
IS_LEAF
(
node
)
||
((
struct
tnode
*
)
node
)
->
pos
>
if
(
IS_LEAF
(
node
)
||
((
struct
tnode
*
)
node
)
->
pos
>
tn
->
pos
+
tn
->
bits
-
1
)
{
if
(
tkey_extract_bits
(
node
->
key
,
oldtnode
->
pos
+
oldtnode
->
bits
,
if
(
tkey_extract_bits
(
node
->
key
,
oldtnode
->
pos
+
oldtnode
->
bits
,
1
)
==
0
)
put_child
(
t
,
tn
,
2
*
i
,
node
);
else
...
...
@@ -745,37 +747,37 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
struct
tnode
*
left
,
*
right
;
int
size
,
j
;
/* We will replace this node 'inode' with two new
* ones, 'left' and 'right', each with half of the
* original children. The two new nodes will have
* a position one bit further down the key and this
* means that the "significant" part of their keys
* (see the discussion near the top of this file)
* will differ by one bit, which will be "0" in
* left's key and "1" in right's key. Since we are
* moving the key position by one step, the bit that
* we are moving away from - the bit at position
* (inode->pos) - is the one that will differ between
/* We will replace this node 'inode' with two new
* ones, 'left' and 'right', each with half of the
* original children. The two new nodes will have
* a position one bit further down the key and this
* means that the "significant" part of their keys
* (see the discussion near the top of this file)
* will differ by one bit, which will be "0" in
* left's key and "1" in right's key. Since we are
* moving the key position by one step, the bit that
* we are moving away from - the bit at position
* (inode->pos) - is the one that will differ between
* left and right. So... we synthesize that bit in the
* two new keys.
* The mask 'm' below will be a single "one" bit at
* The mask 'm' below will be a single "one" bit at
* the position (inode->pos)
*/
/* Use the old key, but set the new significant
* bit to zero.
/* Use the old key, but set the new significant
* bit to zero.
*/
left
=
(
struct
tnode
*
)
tnode_get_child
(
tn
,
2
*
i
);
put_child
(
t
,
tn
,
2
*
i
,
NULL
);
if
(
!
left
)
if
(
!
left
)
BUG
();
right
=
(
struct
tnode
*
)
tnode_get_child
(
tn
,
2
*
i
+
1
);
put_child
(
t
,
tn
,
2
*
i
+
1
,
NULL
);
if
(
!
right
)
if
(
!
right
)
BUG
();
size
=
tnode_child_length
(
left
);
...
...
@@ -800,9 +802,9 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
int
i
;
int
olen
=
tnode_child_length
(
tn
);
if
(
trie_debug
)
printk
(
"In halve
\n
"
);
tn
=
tnode_new
(
oldtnode
->
key
,
oldtnode
->
pos
,
oldtnode
->
bits
-
1
);
if
(
trie_debug
)
printk
(
"In halve
\n
"
);
tn
=
tnode_new
(
oldtnode
->
key
,
oldtnode
->
pos
,
oldtnode
->
bits
-
1
);
if
(
!
tn
)
{
*
err
=
-
ENOMEM
;
...
...
@@ -810,39 +812,39 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
}
/*
* Preallocate and store tnodes before the actual work so we
* don't get into an inconsistent state if memory allocation
* fails. In case of failure we return the oldnode and halve
* Preallocate and store tnodes before the actual work so we
* don't get into an inconsistent state if memory allocation
* fails. In case of failure we return the oldnode and halve
* of tnode is ignored.
*/
for
(
i
=
0
;
i
<
olen
;
i
+=
2
)
{
left
=
tnode_get_child
(
oldtnode
,
i
);
right
=
tnode_get_child
(
oldtnode
,
i
+
1
);
/* Two nonempty children */
if
(
left
&&
right
)
{
if
(
left
&&
right
)
{
struct
tnode
*
newBinNode
=
tnode_new
(
left
->
key
,
tn
->
pos
+
tn
->
bits
,
1
);
if
(
!
newBinNode
)
{
*
err
=
-
ENOMEM
;
if
(
!
newBinNode
)
{
*
err
=
-
ENOMEM
;
break
;
}
put_child
(
t
,
tn
,
i
/
2
,
(
struct
node
*
)
newBinNode
);
}
}
if
(
*
err
)
{
if
(
*
err
)
{
int
size
=
tnode_child_length
(
tn
);
int
j
;
for
(
j
=
0
;
j
<
size
;
j
++
)
if
(
tn
->
child
[
j
])
for
(
j
=
0
;
j
<
size
;
j
++
)
if
(
tn
->
child
[
j
])
tnode_free
((
struct
tnode
*
)
tn
->
child
[
j
]);
tnode_free
(
tn
);
*
err
=
-
ENOMEM
;
return
oldtnode
;
}
...
...
@@ -850,7 +852,7 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
for
(
i
=
0
;
i
<
olen
;
i
+=
2
)
{
left
=
tnode_get_child
(
oldtnode
,
i
);
right
=
tnode_get_child
(
oldtnode
,
i
+
1
);
/* At least one of the children is empty */
if
(
left
==
NULL
)
{
if
(
right
==
NULL
)
/* Both are empty */
...
...
@@ -858,14 +860,14 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
put_child
(
t
,
tn
,
i
/
2
,
right
);
}
else
if
(
right
==
NULL
)
put_child
(
t
,
tn
,
i
/
2
,
left
);
/* Two nonempty children */
else
{
struct
tnode
*
newBinNode
=
(
struct
tnode
*
)
tnode_get_child
(
tn
,
i
/
2
);
put_child
(
t
,
tn
,
i
/
2
,
NULL
);
if
(
!
newBinNode
)
if
(
!
newBinNode
)
BUG
();
put_child
(
t
,
newBinNode
,
0
,
left
);
...
...
@@ -879,7 +881,7 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
static
void
*
trie_init
(
struct
trie
*
t
)
{
if
(
t
)
{
if
(
t
)
{
t
->
size
=
0
;
t
->
trie
=
NULL
;
t
->
revision
=
0
;
...
...
@@ -896,8 +898,7 @@ static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
struct
leaf_info
*
li
;
hlist_for_each_entry
(
li
,
node
,
head
,
hlist
)
{
if
(
li
->
plen
==
plen
)
if
(
li
->
plen
==
plen
)
return
li
;
}
return
NULL
;
...
...
@@ -905,35 +906,35 @@ static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
static
inline
struct
list_head
*
get_fa_head
(
struct
leaf
*
l
,
int
plen
)
{
struct
list_head
*
fa_head
=
NULL
;
struct
list_head
*
fa_head
=
NULL
;
struct
leaf_info
*
li
=
find_leaf_info
(
&
l
->
list
,
plen
);
if
(
li
)
if
(
li
)
fa_head
=
&
li
->
falh
;
return
fa_head
;
}
static
void
insert_leaf_info
(
struct
hlist_head
*
head
,
struct
leaf_info
*
new
)
{
struct
leaf_info
*
li
=
NULL
,
*
last
=
NULL
;
struct
leaf_info
*
li
=
NULL
,
*
last
=
NULL
;
struct
hlist_node
*
node
,
*
tmp
;
write_lock_bh
(
&
fib_lock
);
if
(
hlist_empty
(
head
))
if
(
hlist_empty
(
head
))
hlist_add_head
(
&
new
->
hlist
,
head
);
else
{
hlist_for_each_entry_safe
(
li
,
node
,
tmp
,
head
,
hlist
)
{
if
(
new
->
plen
>
li
->
plen
)
if
(
new
->
plen
>
li
->
plen
)
break
;
last
=
li
;
}
if
(
last
)
if
(
last
)
hlist_add_after
(
&
last
->
hlist
,
&
new
->
hlist
);
else
else
hlist_add_before
(
&
new
->
hlist
,
&
li
->
hlist
);
}
write_unlock_bh
(
&
fib_lock
);
...
...
@@ -947,14 +948,14 @@ fib_find_node(struct trie *t, u32 key)
struct
node
*
n
;
pos
=
0
;
n
=
t
->
trie
;
n
=
t
->
trie
;
while
(
n
!=
NULL
&&
NODE_TYPE
(
n
)
==
T_TNODE
)
{
tn
=
(
struct
tnode
*
)
n
;
check_tnode
(
tn
);
if
(
tkey_sub_equals
(
tn
->
key
,
pos
,
tn
->
pos
-
pos
,
key
))
{
if
(
tkey_sub_equals
(
tn
->
key
,
pos
,
tn
->
pos
-
pos
,
key
))
{
pos
=
tn
->
pos
+
tn
->
bits
;
n
=
tnode_get_child
(
tn
,
tkey_extract_bits
(
key
,
tn
->
pos
,
tn
->
bits
));
}
...
...
@@ -977,23 +978,23 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
t_key
cindex
,
key
;
struct
tnode
*
tp
=
NULL
;
if
(
!
tn
)
if
(
!
tn
)
BUG
();
key
=
tn
->
key
;
i
=
0
;
while
(
tn
!=
NULL
&&
NODE_PARENT
(
tn
)
!=
NULL
)
{
if
(
i
>
10
)
{
if
(
i
>
10
)
{
printk
(
"Rebalance tn=%p
\n
"
,
tn
);
if
(
tn
)
printk
(
"tn->parent=%p
\n
"
,
NODE_PARENT
(
tn
));
if
(
tn
)
printk
(
"tn->parent=%p
\n
"
,
NODE_PARENT
(
tn
));
printk
(
"Rebalance tp=%p
\n
"
,
tp
);
if
(
tp
)
printk
(
"tp->parent=%p
\n
"
,
NODE_PARENT
(
tp
));
if
(
tp
)
printk
(
"tp->parent=%p
\n
"
,
NODE_PARENT
(
tp
));
}
if
(
i
>
12
)
BUG
();
if
(
i
>
12
)
BUG
();
i
++
;
tp
=
NODE_PARENT
(
tn
);
...
...
@@ -1001,14 +1002,14 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
wasfull
=
tnode_full
(
tp
,
tnode_get_child
(
tp
,
cindex
));
tn
=
(
struct
tnode
*
)
resize
(
t
,
(
struct
tnode
*
)
tn
);
tnode_put_child_reorg
((
struct
tnode
*
)
tp
,
cindex
,(
struct
node
*
)
tn
,
wasfull
);
if
(
!
NODE_PARENT
(
tn
))
if
(
!
NODE_PARENT
(
tn
))
break
;
tn
=
NODE_PARENT
(
tn
);
}
/* Handle last (top) tnode */
if
(
IS_TNODE
(
tn
))
if
(
IS_TNODE
(
tn
))
tn
=
(
struct
tnode
*
)
resize
(
t
,
(
struct
tnode
*
)
tn
);
return
(
struct
node
*
)
tn
;
...
...
@@ -1022,42 +1023,42 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
struct
node
*
n
;
struct
leaf
*
l
;
int
missbit
;
struct
list_head
*
fa_head
=
NULL
;
struct
list_head
*
fa_head
=
NULL
;
struct
leaf_info
*
li
;
t_key
cindex
;
pos
=
0
;
n
=
t
->
trie
;
n
=
t
->
trie
;
/* If we point to NULL, stop. Either the tree is empty and we should
* just put a new leaf in if, or we have reached an empty child slot,
/* If we point to NULL, stop. Either the tree is empty and we should
* just put a new leaf in if, or we have reached an empty child slot,
* and we should just put our new leaf in that.
* If we point to a T_TNODE, check if it matches our key. Note that
* a T_TNODE might be skipping any number of bits - its 'pos' need
* If we point to a T_TNODE, check if it matches our key. Note that
* a T_TNODE might be skipping any number of bits - its 'pos' need
* not be the parent's 'pos'+'bits'!
*
* If it does match the current key, get pos/bits from it, extract
* If it does match the current key, get pos/bits from it, extract
* the index from our key, push the T_TNODE and walk the tree.
*
* If it doesn't, we have to replace it with a new T_TNODE.
*
* If we point to a T_LEAF, it might or might not have the same key
* as we do. If it does, just change the value, update the T_LEAF's
* value, and return it.
* If we point to a T_LEAF, it might or might not have the same key
* as we do. If it does, just change the value, update the T_LEAF's
* value, and return it.
* If it doesn't, we need to replace it with a T_TNODE.
*/
while
(
n
!=
NULL
&&
NODE_TYPE
(
n
)
==
T_TNODE
)
{
tn
=
(
struct
tnode
*
)
n
;
check_tnode
(
tn
);
if
(
tkey_sub_equals
(
tn
->
key
,
pos
,
tn
->
pos
-
pos
,
key
))
{
check_tnode
(
tn
);
if
(
tkey_sub_equals
(
tn
->
key
,
pos
,
tn
->
pos
-
pos
,
key
))
{
tp
=
tn
;
pos
=
tn
->
pos
+
tn
->
bits
;
n
=
tnode_get_child
(
tn
,
tkey_extract_bits
(
key
,
tn
->
pos
,
tn
->
bits
));
if
(
n
&&
NODE_PARENT
(
n
)
!=
tn
)
{
if
(
n
&&
NODE_PARENT
(
n
)
!=
tn
)
{
printk
(
"BUG tn=%p, n->parent=%p
\n
"
,
tn
,
NODE_PARENT
(
n
));
BUG
();
}
...
...
@@ -1069,21 +1070,21 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
/*
* n ----> NULL, LEAF or TNODE
*
* tp is n's (parent) ----> NULL or TNODE
* tp is n's (parent) ----> NULL or TNODE
*/
if
(
tp
&&
IS_LEAF
(
tp
))
if
(
tp
&&
IS_LEAF
(
tp
))
BUG
();
/* Case 1: n is a leaf. Compare prefixes */
if
(
n
!=
NULL
&&
IS_LEAF
(
n
)
&&
tkey_equals
(
key
,
n
->
key
))
{
if
(
n
!=
NULL
&&
IS_LEAF
(
n
)
&&
tkey_equals
(
key
,
n
->
key
))
{
struct
leaf
*
l
=
(
struct
leaf
*
)
n
;
li
=
leaf_info_new
(
plen
);
if
(
!
li
)
{
if
(
!
li
)
{
*
err
=
-
ENOMEM
;
goto
err
;
}
...
...
@@ -1095,7 +1096,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
t
->
size
++
;
l
=
leaf_new
();
if
(
!
l
)
{
if
(
!
l
)
{
*
err
=
-
ENOMEM
;
goto
err
;
}
...
...
@@ -1103,7 +1104,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
l
->
key
=
key
;
li
=
leaf_info_new
(
plen
);
if
(
!
li
)
{
if
(
!
li
)
{
tnode_free
((
struct
tnode
*
)
l
);
*
err
=
-
ENOMEM
;
goto
err
;
...
...
@@ -1116,8 +1117,8 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
if
(
t
->
trie
&&
n
==
NULL
)
{
NODE_SET_PARENT
(
l
,
tp
);
if
(
!
tp
)
if
(
!
tp
)
BUG
();
else
{
...
...
@@ -1127,8 +1128,8 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
}
/* Case 3: n is a LEAF or a TNODE and the key doesn't match. */
else
{
/*
* Add a new tnode here
/*
* Add a new tnode here
* first tnode need some special handling
*/
...
...
@@ -1136,39 +1137,39 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
pos
=
tp
->
pos
+
tp
->
bits
;
else
pos
=
0
;
if
(
n
)
{
if
(
n
)
{
newpos
=
tkey_mismatch
(
key
,
pos
,
n
->
key
);
tn
=
tnode_new
(
n
->
key
,
newpos
,
1
);
}
else
{
newpos
=
0
;
tn
=
tnode_new
(
key
,
newpos
,
1
);
/* First tnode */
tn
=
tnode_new
(
key
,
newpos
,
1
);
/* First tnode */
}
if
(
!
tn
)
{
if
(
!
tn
)
{
free_leaf_info
(
li
);
tnode_free
((
struct
tnode
*
)
l
);
*
err
=
-
ENOMEM
;
goto
err
;
}
}
NODE_SET_PARENT
(
tn
,
tp
);
missbit
=
tkey_extract_bits
(
key
,
newpos
,
1
);
put_child
(
t
,
tn
,
missbit
,
(
struct
node
*
)
l
);
put_child
(
t
,
tn
,
1
-
missbit
,
n
);
if
(
tp
)
{
if
(
tp
)
{
cindex
=
tkey_extract_bits
(
key
,
tp
->
pos
,
tp
->
bits
);
put_child
(
t
,
(
struct
tnode
*
)
tp
,
cindex
,
(
struct
node
*
)
tn
);
}
else
{
else
{
t
->
trie
=
(
struct
node
*
)
tn
;
/* First tnode */
tp
=
tn
;
}
}
if
(
tp
&&
tp
->
pos
+
tp
->
bits
>
32
)
{
printk
(
"ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d
\n
"
,
if
(
tp
&&
tp
->
pos
+
tp
->
bits
>
32
)
{
printk
(
"ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d
\n
"
,
tp
,
tp
->
pos
,
tp
->
bits
,
key
,
plen
);
}
/* Rebalance the trie */
...
...
@@ -1185,7 +1186,7 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
{
struct
trie
*
t
=
(
struct
trie
*
)
tb
->
tb_data
;
struct
fib_alias
*
fa
,
*
new_fa
;
struct
list_head
*
fa_head
=
NULL
;
struct
list_head
*
fa_head
=
NULL
;
struct
fib_info
*
fi
;
int
plen
=
r
->
rtm_dst_len
;
int
type
=
r
->
rtm_type
;
...
...
@@ -1198,17 +1199,17 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
return
-
EINVAL
;
key
=
0
;
if
(
rta
->
rta_dst
)
if
(
rta
->
rta_dst
)
memcpy
(
&
key
,
rta
->
rta_dst
,
4
);
key
=
ntohl
(
key
);
if
(
trie_debug
)
if
(
trie_debug
)
printk
(
"Insert table=%d %08x/%d
\n
"
,
tb
->
tb_id
,
key
,
plen
);
mask
=
ntohl
(
inet_make_mask
(
plen
)
);
mask
=
ntohl
(
inet_make_mask
(
plen
)
);
if
(
key
&
~
mask
)
if
(
key
&
~
mask
)
return
-
EINVAL
;
key
=
key
&
mask
;
...
...
@@ -1217,9 +1218,9 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
goto
err
;
l
=
fib_find_node
(
t
,
key
);
fa
=
NULL
;
fa
=
NULL
;
if
(
l
)
{
if
(
l
)
{
fa_head
=
get_fa_head
(
l
,
plen
);
fa
=
fib_find_alias
(
fa_head
,
tos
,
fi
->
fib_priority
);
}
...
...
@@ -1298,16 +1299,16 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
new_fa
->
fa_scope
=
r
->
rtm_scope
;
new_fa
->
fa_state
=
0
;
#if 0
new_fa->dst
= NULL;
new_fa->dst = NULL;
#endif
/*
* Insert new entry to the list.
*/
if
(
!
fa_head
)
{
if
(
!
fa_head
)
{
fa_head
=
fib_insert_node
(
t
,
&
err
,
key
,
plen
);
err
=
0
;
if
(
err
)
if
(
err
)
goto
out_free_new_fa
;
}
...
...
@@ -1327,11 +1328,11 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
kmem_cache_free
(
fn_alias_kmem
,
new_fa
);
out:
fib_release_info
(
fi
);
err:
;
err:
;
return
err
;
}
static
inline
int
check_leaf
(
struct
trie
*
t
,
struct
leaf
*
l
,
t_key
key
,
int
*
plen
,
const
struct
flowi
*
flp
,
static
inline
int
check_leaf
(
struct
trie
*
t
,
struct
leaf
*
l
,
t_key
key
,
int
*
plen
,
const
struct
flowi
*
flp
,
struct
fib_result
*
res
,
int
*
err
)
{
int
i
;
...
...
@@ -1339,12 +1340,12 @@ static inline int check_leaf(struct trie *t, struct leaf *l, t_key key, int *pl
struct
leaf_info
*
li
;
struct
hlist_head
*
hhead
=
&
l
->
list
;
struct
hlist_node
*
node
;
hlist_for_each_entry
(
li
,
node
,
hhead
,
hlist
)
{
i
=
li
->
plen
;
mask
=
ntohl
(
inet_make_mask
(
i
));
if
(
l
->
key
!=
(
key
&
mask
))
if
(
l
->
key
!=
(
key
&
mask
))
continue
;
if
(((
*
err
)
=
fib_semantic_match
(
&
li
->
falh
,
flp
,
res
,
l
->
key
,
mask
,
i
))
==
0
)
{
...
...
@@ -1376,7 +1377,7 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
n
=
t
->
trie
;
read_lock
(
&
fib_lock
);
if
(
!
n
)
if
(
!
n
)
goto
failed
;
#ifdef CONFIG_IP_FIB_TRIE_STATS
...
...
@@ -1385,19 +1386,19 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
/* Just a leaf? */
if
(
IS_LEAF
(
n
))
{
if
(
check_leaf
(
t
,
(
struct
leaf
*
)
n
,
key
,
&
plen
,
flp
,
res
,
&
ret
)
)
if
(
check_leaf
(
t
,
(
struct
leaf
*
)
n
,
key
,
&
plen
,
flp
,
res
,
&
ret
)
)
goto
found
;
goto
failed
;
}
pn
=
(
struct
tnode
*
)
n
;
chopped_off
=
0
;
while
(
pn
)
{
pos
=
pn
->
pos
;
bits
=
pn
->
bits
;
if
(
!
chopped_off
)
if
(
!
chopped_off
)
cindex
=
tkey_extract_bits
(
MASK_PFX
(
key
,
current_prefix_length
),
pos
,
bits
);
n
=
tnode_get_child
(
pn
,
cindex
);
...
...
@@ -1417,33 +1418,33 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
int
mp
;
/*
* It's a tnode, and we can do some extra checks here if we
* It's a tnode, and we can do some extra checks here if we
* like, to avoid descending into a dead-end branch.
* This tnode is in the parent's child array at index
* key[p_pos..p_pos+p_bits] but potentially with some bits
* chopped off, so in reality the index may be just a
* This tnode is in the parent's child array at index
* key[p_pos..p_pos+p_bits] but potentially with some bits
* chopped off, so in reality the index may be just a
* subprefix, padded with zero at the end.
* We can also take a look at any skipped bits in this
* tnode - everything up to p_pos is supposed to be ok,
* We can also take a look at any skipped bits in this
* tnode - everything up to p_pos is supposed to be ok,
* and the non-chopped bits of the index (se previous
* paragraph) are also guaranteed ok, but the rest is
* paragraph) are also guaranteed ok, but the rest is
* considered unknown.
*
* The skipped bits are key[pos+bits..cn->pos].
*/
/* If current_prefix_length < pos+bits, we are already doing
* actual prefix matching, which means everything from
* pos+(bits-chopped_off) onward must be zero along some
* branch of this subtree - otherwise there is *no* valid
/* If current_prefix_length < pos+bits, we are already doing
* actual prefix matching, which means everything from
* pos+(bits-chopped_off) onward must be zero along some
* branch of this subtree - otherwise there is *no* valid
* prefix present. Here we can only check the skipped
* bits. Remember, since we have already indexed into the
* parent's child array, we know that the bits we chopped of
* bits. Remember, since we have already indexed into the
* parent's child array, we know that the bits we chopped of
* *are* zero.
*/
/* NOTA BENE: CHECKING ONLY SKIPPED BITS FOR THE NEW NODE HERE */
if
(
current_prefix_length
<
pos
+
bits
)
{
if
(
tkey_extract_bits
(
cn
->
key
,
current_prefix_length
,
cn
->
pos
-
current_prefix_length
)
!=
0
||
...
...
@@ -1452,13 +1453,13 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
}
/*
* If chopped_off=0, the index is fully validated and we
* only need to look at the skipped bits for this, the new,
* If chopped_off=0, the index is fully validated and we
* only need to look at the skipped bits for this, the new,
* tnode. What we actually want to do is to find out if
* these skipped bits match our key perfectly, or if we will
* have to count on finding a matching prefix further down,
* because if we do, we would like to have some way of
* verifying the existence of such a prefix at this point.
* have to count on finding a matching prefix further down,
* because if we do, we would like to have some way of
* verifying the existence of such a prefix at this point.
*/
/* The only thing we can do at this point is to verify that
...
...
@@ -1470,22 +1471,22 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
* new tnode's key.
*/
/* Note: We aren't very concerned about the piece of the key
* that precede pn->pos+pn->bits, since these have already been
* checked. The bits after cn->pos aren't checked since these are
* by definition "unknown" at this point. Thus, what we want to
* see is if we are about to enter the "prefix matching" state,
* and in that case verify that the skipped bits that will prevail
* throughout this subtree are zero, as they have to be if we are
/* Note: We aren't very concerned about the piece of the key
* that precede pn->pos+pn->bits, since these have already been
* checked. The bits after cn->pos aren't checked since these are
* by definition "unknown" at this point. Thus, what we want to
* see is if we are about to enter the "prefix matching" state,
* and in that case verify that the skipped bits that will prevail
* throughout this subtree are zero, as they have to be if we are
* to find a matching prefix.
*/
node_prefix
=
MASK_PFX
(
cn
->
key
,
cn
->
pos
);
key_prefix
=
MASK_PFX
(
key
,
cn
->
pos
);
key_prefix
=
MASK_PFX
(
key
,
cn
->
pos
);
pref_mismatch
=
key_prefix
^
node_prefix
;
mp
=
0
;
/* In short: If skipped bits in this node do not match the search
/* In short: If skipped bits in this node do not match the search
* key, enter the "prefix matching" state.directly.
*/
if
(
pref_mismatch
)
{
...
...
@@ -1494,7 +1495,7 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
pref_mismatch
=
pref_mismatch
<<
1
;
}
key_prefix
=
tkey_extract_bits
(
cn
->
key
,
mp
,
cn
->
pos
-
mp
);
if
(
key_prefix
!=
0
)
goto
backtrace
;
...
...
@@ -1505,9 +1506,9 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
pn
=
(
struct
tnode
*
)
n
;
/* Descend */
chopped_off
=
0
;
continue
;
}
if
(
IS_LEAF
(
n
))
{
if
(
check_leaf
(
t
,
(
struct
leaf
*
)
n
,
key
,
&
plen
,
flp
,
res
,
&
ret
))
}
if
(
IS_LEAF
(
n
))
{
if
(
check_leaf
(
t
,
(
struct
leaf
*
)
n
,
key
,
&
plen
,
flp
,
res
,
&
ret
))
goto
found
;
}
backtrace:
...
...
@@ -1521,18 +1522,18 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
/* Decrease current_... with bits chopped off */
if
(
current_prefix_length
>
pn
->
pos
+
pn
->
bits
-
chopped_off
)
current_prefix_length
=
pn
->
pos
+
pn
->
bits
-
chopped_off
;
/*
* Either we do the actual chop off according or if we have
* Either we do the actual chop off according or if we have
* chopped off all bits in this tnode walk up to our parent.
*/
if
(
chopped_off
<=
pn
->
bits
)
if
(
chopped_off
<=
pn
->
bits
)
cindex
&=
~
(
1
<<
(
chopped_off
-
1
));
else
{
if
(
NODE_PARENT
(
pn
)
==
NULL
)
if
(
NODE_PARENT
(
pn
)
==
NULL
)
goto
failed
;
/* Get Child's index */
cindex
=
tkey_extract_bits
(
pn
->
key
,
NODE_PARENT
(
pn
)
->
pos
,
NODE_PARENT
(
pn
)
->
bits
);
pn
=
NODE_PARENT
(
pn
);
...
...
@@ -1542,10 +1543,10 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
t
->
stats
.
backtrack
++
;
#endif
goto
backtrace
;
}
}
}
failed:
ret
=
1
;
ret
=
1
;
found:
read_unlock
(
&
fib_lock
);
return
ret
;
...
...
@@ -1558,11 +1559,11 @@ static int trie_leaf_remove(struct trie *t, t_key key)
struct
node
*
n
=
t
->
trie
;
struct
leaf
*
l
;
if
(
trie_debug
)
if
(
trie_debug
)
printk
(
"entering trie_leaf_remove(%p)
\n
"
,
n
);
/* Note that in the case skipped bits, those bits are *not* checked!
* When we finish this, we will have NULL or a T_LEAF, and the
* When we finish this, we will have NULL or a T_LEAF, and the
* T_LEAF may or may not match our key.
*/
...
...
@@ -1571,19 +1572,19 @@ static int trie_leaf_remove(struct trie *t, t_key key)
check_tnode
(
tn
);
n
=
tnode_get_child
(
tn
,
tkey_extract_bits
(
key
,
tn
->
pos
,
tn
->
bits
));
if
(
n
&&
NODE_PARENT
(
n
)
!=
tn
)
{
if
(
n
&&
NODE_PARENT
(
n
)
!=
tn
)
{
printk
(
"BUG tn=%p, n->parent=%p
\n
"
,
tn
,
NODE_PARENT
(
n
));
BUG
();
}
}
l
=
(
struct
leaf
*
)
n
;
if
(
!
n
||
!
tkey_equals
(
l
->
key
,
key
))
if
(
!
n
||
!
tkey_equals
(
l
->
key
,
key
))
return
0
;
/*
* Key found.
* Remove the leaf and rebalance the tree
/*
* Key found.
* Remove the leaf and rebalance the tree
*/
t
->
revision
++
;
...
...
@@ -1592,7 +1593,7 @@ static int trie_leaf_remove(struct trie *t, t_key key)
tp
=
NODE_PARENT
(
n
);
tnode_free
((
struct
tnode
*
)
n
);
if
(
tp
)
{
if
(
tp
)
{
cindex
=
tkey_extract_bits
(
key
,
tp
->
pos
,
tp
->
bits
);
put_child
(
t
,
(
struct
tnode
*
)
tp
,
cindex
,
NULL
);
t
->
trie
=
trie_rebalance
(
t
,
tp
);
...
...
@@ -1615,23 +1616,23 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
struct
list_head
*
fa_head
;
struct
leaf
*
l
;
if
(
plen
>
32
)
if
(
plen
>
32
)
return
-
EINVAL
;
key
=
0
;
if
(
rta
->
rta_dst
)
if
(
rta
->
rta_dst
)
memcpy
(
&
key
,
rta
->
rta_dst
,
4
);
key
=
ntohl
(
key
);
mask
=
ntohl
(
inet_make_mask
(
plen
)
);
mask
=
ntohl
(
inet_make_mask
(
plen
)
);
if
(
key
&
~
mask
)
if
(
key
&
~
mask
)
return
-
EINVAL
;
key
=
key
&
mask
;
l
=
fib_find_node
(
t
,
key
);
if
(
!
l
)
if
(
!
l
)
return
-
ESRCH
;
fa_head
=
get_fa_head
(
l
,
plen
);
...
...
@@ -1677,16 +1678,16 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
list_del
(
&
fa
->
fa_list
);
if
(
list_empty
(
fa_head
))
{
if
(
list_empty
(
fa_head
))
{
hlist_del
(
&
li
->
hlist
);
kill_li
=
1
;
}
write_unlock_bh
(
&
fib_lock
);
if
(
kill_li
)
if
(
kill_li
)
free_leaf_info
(
li
);
if
(
hlist_empty
(
&
l
->
list
))
if
(
hlist_empty
(
&
l
->
list
))
trie_leaf_remove
(
t
,
key
);
if
(
fa
->
fa_state
&
FA_S_ACCESSED
)
...
...
@@ -1705,12 +1706,12 @@ static int trie_flush_list(struct trie *t, struct list_head *head)
list_for_each_entry_safe
(
fa
,
fa_node
,
head
,
fa_list
)
{
struct
fib_info
*
fi
=
fa
->
fa_info
;
if
(
fi
&&
(
fi
->
fib_flags
&
RTNH_F_DEAD
))
{
write_lock_bh
(
&
fib_lock
);
write_lock_bh
(
&
fib_lock
);
list_del
(
&
fa
->
fa_list
);
write_unlock_bh
(
&
fib_lock
);
write_unlock_bh
(
&
fib_lock
);
fn_free_alias
(
fa
);
found
++
;
...
...
@@ -1727,14 +1728,14 @@ static int trie_flush_leaf(struct trie *t, struct leaf *l)
struct
leaf_info
*
li
=
NULL
;
hlist_for_each_entry_safe
(
li
,
node
,
tmp
,
lih
,
hlist
)
{
found
+=
trie_flush_list
(
t
,
&
li
->
falh
);
if
(
list_empty
(
&
li
->
falh
))
{
write_lock_bh
(
&
fib_lock
);
write_lock_bh
(
&
fib_lock
);
hlist_del
(
&
li
->
hlist
);
write_unlock_bh
(
&
fib_lock
);
write_unlock_bh
(
&
fib_lock
);
free_leaf_info
(
li
);
}
...
...
@@ -1748,8 +1749,8 @@ static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
struct
tnode
*
p
;
int
idx
;
if
(
c
==
NULL
)
{
if
(
t
->
trie
==
NULL
)
if
(
c
==
NULL
)
{
if
(
t
->
trie
==
NULL
)
return
NULL
;
if
(
IS_LEAF
(
t
->
trie
))
/* trie w. just a leaf */
...
...
@@ -1757,33 +1758,34 @@ static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
p
=
(
struct
tnode
*
)
t
->
trie
;
/* Start */
}
else
else
p
=
(
struct
tnode
*
)
NODE_PARENT
(
c
);
while
(
p
)
{
int
pos
,
last
;
/* Find the next child of the parent */
if
(
c
)
pos
=
1
+
tkey_extract_bits
(
c
->
key
,
p
->
pos
,
p
->
bits
);
else
if
(
c
)
pos
=
1
+
tkey_extract_bits
(
c
->
key
,
p
->
pos
,
p
->
bits
);
else
pos
=
0
;
last
=
1
<<
p
->
bits
;
for
(
idx
=
pos
;
idx
<
last
;
idx
++
)
{
if
(
p
->
child
[
idx
])
{
if
(
p
->
child
[
idx
])
{
/* Decend if tnode */
while
(
IS_TNODE
(
p
->
child
[
idx
]))
{
p
=
(
struct
tnode
*
)
p
->
child
[
idx
];
idx
=
0
;
/* Rightmost non-NULL branch */
if
(
p
&&
IS_TNODE
(
p
)
)
while
(
p
->
child
[
idx
]
==
NULL
&&
idx
<
(
1
<<
p
->
bits
)
)
idx
++
;
if
(
p
&&
IS_TNODE
(
p
)
)
while
(
p
->
child
[
idx
]
==
NULL
&&
idx
<
(
1
<<
p
->
bits
)
)
idx
++
;
/* Done with this tnode? */
if
(
idx
>=
(
1
<<
p
->
bits
)
||
p
->
child
[
idx
]
==
NULL
)
if
(
idx
>=
(
1
<<
p
->
bits
)
||
p
->
child
[
idx
]
==
NULL
)
goto
up
;
}
return
(
struct
leaf
*
)
p
->
child
[
idx
];
...
...
@@ -1816,7 +1818,7 @@ static int fn_trie_flush(struct fib_table *tb)
if
(
ll
&&
hlist_empty
(
&
ll
->
list
))
trie_leaf_remove
(
t
,
ll
->
key
);
if
(
trie_debug
)
if
(
trie_debug
)
printk
(
"trie_flush found=%d
\n
"
,
found
);
return
found
;
}
...
...
@@ -1839,32 +1841,32 @@ fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
order
=
-
1
;
read_lock
(
&
fib_lock
);
l
=
fib_find_node
(
t
,
0
);
if
(
!
l
)
if
(
!
l
)
goto
out
;
fa_head
=
get_fa_head
(
l
,
0
);
if
(
!
fa_head
)
if
(
!
fa_head
)
goto
out
;
if
(
list_empty
(
fa_head
))
if
(
list_empty
(
fa_head
))
goto
out
;
list_for_each_entry
(
fa
,
fa_head
,
fa_list
)
{
struct
fib_info
*
next_fi
=
fa
->
fa_info
;
if
(
fa
->
fa_scope
!=
res
->
scope
||
fa
->
fa_type
!=
RTN_UNICAST
)
continue
;
if
(
next_fi
->
fib_priority
>
res
->
fi
->
fib_priority
)
break
;
if
(
!
next_fi
->
fib_nh
[
0
].
nh_gw
||
next_fi
->
fib_nh
[
0
].
nh_scope
!=
RT_SCOPE_LINK
)
continue
;
fa
->
fa_state
|=
FA_S_ACCESSED
;
if
(
fi
==
NULL
)
{
if
(
next_fi
!=
res
->
fi
)
break
;
...
...
@@ -1902,10 +1904,10 @@ fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
}
trie_last_dflt
=
last_idx
;
out:
;
read_unlock
(
&
fib_lock
);
read_unlock
(
&
fib_lock
);
}
static
int
fn_trie_dump_fa
(
t_key
key
,
int
plen
,
struct
list_head
*
fah
,
struct
fib_table
*
tb
,
static
int
fn_trie_dump_fa
(
t_key
key
,
int
plen
,
struct
list_head
*
fah
,
struct
fib_table
*
tb
,
struct
sk_buff
*
skb
,
struct
netlink_callback
*
cb
)
{
int
i
,
s_i
;
...
...
@@ -1951,7 +1953,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
return
skb
->
len
;
}
static
int
fn_trie_dump_plen
(
struct
trie
*
t
,
int
plen
,
struct
fib_table
*
tb
,
struct
sk_buff
*
skb
,
static
int
fn_trie_dump_plen
(
struct
trie
*
t
,
int
plen
,
struct
fib_table
*
tb
,
struct
sk_buff
*
skb
,
struct
netlink_callback
*
cb
)
{
int
h
,
s_h
;
...
...
@@ -1968,11 +1970,11 @@ static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb, str
sizeof
(
cb
->
args
)
-
3
*
sizeof
(
cb
->
args
[
0
]));
fa_head
=
get_fa_head
(
l
,
plen
);
if
(
!
fa_head
)
if
(
!
fa_head
)
continue
;
if
(
list_empty
(
fa_head
))
if
(
list_empty
(
fa_head
))
continue
;
if
(
fn_trie_dump_fa
(
l
->
key
,
plen
,
fa_head
,
tb
,
skb
,
cb
)
<
0
)
{
...
...
@@ -2048,10 +2050,10 @@ struct fib_table * __init fib_hash_init(int id)
trie_init
(
t
);
if
(
id
==
RT_TABLE_LOCAL
)
trie_local
=
t
;
else
if
(
id
==
RT_TABLE_MAIN
)
trie_main
=
t
;
if
(
id
==
RT_TABLE_LOCAL
)
trie_local
=
t
;
else
if
(
id
==
RT_TABLE_MAIN
)
trie_main
=
t
;
if
(
id
==
RT_TABLE_LOCAL
)
printk
(
"IPv4 FIB: Using LC-trie version %s
\n
"
,
VERSION
);
...
...
@@ -2072,7 +2074,7 @@ static void printbin_seq(struct seq_file *seq, unsigned int v, int bits)
seq_printf
(
seq
,
"%s"
,
(
v
&
(
1
<<
bits
))
?
"1"
:
"0"
);
}
static
void
printnode_seq
(
struct
seq_file
*
seq
,
int
indent
,
struct
node
*
n
,
static
void
printnode_seq
(
struct
seq_file
*
seq
,
int
indent
,
struct
node
*
n
,
int
pend
,
int
cindex
,
int
bits
)
{
putspace_seq
(
seq
,
indent
);
...
...
@@ -2090,12 +2092,12 @@ static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
seq_printf
(
seq
,
"%s:%p "
,
IS_LEAF
(
n
)
?
"Leaf"
:
"Internal node"
,
n
);
if
(
IS_LEAF
(
n
))
seq_printf
(
seq
,
"key=%d.%d.%d.%d
\n
"
,
seq_printf
(
seq
,
"key=%d.%d.%d.%d
\n
"
,
n
->
key
>>
24
,
(
n
->
key
>>
16
)
%
256
,
(
n
->
key
>>
8
)
%
256
,
n
->
key
%
256
);
else
{
int
plen
=
((
struct
tnode
*
)
n
)
->
pos
;
int
plen
=
((
struct
tnode
*
)
n
)
->
pos
;
t_key
prf
=
MASK_PFX
(
n
->
key
,
plen
);
seq_printf
(
seq
,
"key=%d.%d.%d.%d/%d
\n
"
,
seq_printf
(
seq
,
"key=%d.%d.%d.%d/%d
\n
"
,
prf
>>
24
,
(
prf
>>
16
)
%
256
,
(
prf
>>
8
)
%
256
,
prf
%
256
,
plen
);
}
if
(
IS_LEAF
(
n
))
{
...
...
@@ -2103,14 +2105,14 @@ static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
struct
fib_alias
*
fa
;
int
i
;
for
(
i
=
32
;
i
>=
0
;
i
--
)
if
(
find_leaf_info
(
&
l
->
list
,
i
))
{
if
(
find_leaf_info
(
&
l
->
list
,
i
))
{
struct
list_head
*
fa_head
=
get_fa_head
(
l
,
i
);
if
(
!
fa_head
)
if
(
!
fa_head
)
continue
;
if
(
list_empty
(
fa_head
))
if
(
list_empty
(
fa_head
))
continue
;
putspace_seq
(
seq
,
indent
+
2
);
...
...
@@ -2136,7 +2138,7 @@ static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
}
}
else
if
(
IS_TNODE
(
n
))
{
struct
tnode
*
tn
=
(
struct
tnode
*
)
n
;
struct
tnode
*
tn
=
(
struct
tnode
*
)
n
;
putspace_seq
(
seq
,
indent
);
seq_printf
(
seq
,
"| "
);
seq_printf
(
seq
,
"{key prefix=%08x/"
,
tn
->
key
&
TKEY_GET_MASK
(
0
,
tn
->
pos
));
printbin_seq
(
seq
,
tkey_extract_bits
(
tn
->
key
,
0
,
tn
->
pos
),
tn
->
pos
);
...
...
@@ -2152,7 +2154,7 @@ static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
static
void
trie_dump_seq
(
struct
seq_file
*
seq
,
struct
trie
*
t
)
{
struct
node
*
n
=
t
->
trie
;
struct
node
*
n
=
t
->
trie
;
int
cindex
=
0
;
int
indent
=
1
;
int
pend
=
0
;
...
...
@@ -2164,7 +2166,7 @@ static void trie_dump_seq(struct seq_file *seq, struct trie *t)
if
(
n
)
{
printnode_seq
(
seq
,
indent
,
n
,
pend
,
cindex
,
0
);
if
(
IS_TNODE
(
n
))
{
struct
tnode
*
tn
=
(
struct
tnode
*
)
n
;
struct
tnode
*
tn
=
(
struct
tnode
*
)
n
;
pend
=
tn
->
pos
+
tn
->
bits
;
putspace_seq
(
seq
,
indent
);
seq_printf
(
seq
,
"
\\
--
\n
"
);
indent
+=
3
;
...
...
@@ -2172,42 +2174,42 @@ static void trie_dump_seq(struct seq_file *seq, struct trie *t)
while
(
tn
&&
cindex
<
(
1
<<
tn
->
bits
))
{
if
(
tn
->
child
[
cindex
])
{
/* Got a child */
printnode_seq
(
seq
,
indent
,
tn
->
child
[
cindex
],
pend
,
cindex
,
tn
->
bits
);
if
(
IS_LEAF
(
tn
->
child
[
cindex
]))
{
if
(
IS_LEAF
(
tn
->
child
[
cindex
]))
{
cindex
++
;
}
else
{
/*
* New tnode. Decend one level
/*
* New tnode. Decend one level
*/
depth
++
;
n
=
tn
->
child
[
cindex
];
tn
=
(
struct
tnode
*
)
n
;
pend
=
tn
->
pos
+
tn
->
bits
;
n
=
tn
->
child
[
cindex
];
tn
=
(
struct
tnode
*
)
n
;
pend
=
tn
->
pos
+
tn
->
bits
;
putspace_seq
(
seq
,
indent
);
seq_printf
(
seq
,
"
\\
--
\n
"
);
indent
+=
3
;
cindex
=
0
;
}
}
else
else
cindex
++
;
/*
* Test if we are done
* Test if we are done
*/
while
(
cindex
>=
(
1
<<
tn
->
bits
))
{
/*
* Move upwards and test for root
* pop off all traversed nodes
*/
if
(
NODE_PARENT
(
tn
)
==
NULL
)
{
tn
=
NULL
;
n
=
NULL
;
...
...
@@ -2217,8 +2219,8 @@ static void trie_dump_seq(struct seq_file *seq, struct trie *t)
cindex
=
tkey_extract_bits
(
tn
->
key
,
NODE_PARENT
(
tn
)
->
pos
,
NODE_PARENT
(
tn
)
->
bits
);
tn
=
NODE_PARENT
(
tn
);
cindex
++
;
n
=
(
struct
node
*
)
tn
;
pend
=
tn
->
pos
+
tn
->
bits
;
n
=
(
struct
node
*
)
tn
;
pend
=
tn
->
pos
+
tn
->
bits
;
indent
-=
3
;
depth
--
;
}
...
...
@@ -2236,36 +2238,36 @@ static struct trie_stat *trie_stat_new(void)
{
struct
trie_stat
*
s
=
kmalloc
(
sizeof
(
struct
trie_stat
),
GFP_KERNEL
);
int
i
;
if
(
s
)
{
if
(
s
)
{
s
->
totdepth
=
0
;
s
->
maxdepth
=
0
;
s
->
tnodes
=
0
;
s
->
leaves
=
0
;
s
->
nullpointers
=
0
;
for
(
i
=
0
;
i
<
MAX_CHILDS
;
i
++
)
s
->
nodesizes
[
i
]
=
0
;
}
return
s
;
}
}
static
struct
trie_stat
*
trie_collect_stats
(
struct
trie
*
t
)
{
struct
node
*
n
=
t
->
trie
;
struct
node
*
n
=
t
->
trie
;
struct
trie_stat
*
s
=
trie_stat_new
();
int
cindex
=
0
;
int
indent
=
1
;
int
pend
=
0
;
int
depth
=
0
;
read_lock
(
&
fib_lock
);
read_lock
(
&
fib_lock
);
if
(
s
)
{
if
(
n
)
{
if
(
IS_TNODE
(
n
))
{
struct
tnode
*
tn
=
(
struct
tnode
*
)
n
;
pend
=
tn
->
pos
+
tn
->
bits
;
pend
=
tn
->
pos
+
tn
->
bits
;
indent
+=
3
;
s
->
nodesizes
[
tn
->
bits
]
++
;
depth
++
;
...
...
@@ -2273,26 +2275,26 @@ static struct trie_stat *trie_collect_stats(struct trie *t)
while
(
tn
&&
cindex
<
(
1
<<
tn
->
bits
))
{
if
(
tn
->
child
[
cindex
])
{
/* Got a child */
if
(
IS_LEAF
(
tn
->
child
[
cindex
]))
{
if
(
IS_LEAF
(
tn
->
child
[
cindex
]))
{
cindex
++
;
/* stats */
if
(
depth
>
s
->
maxdepth
)
s
->
maxdepth
=
depth
;
s
->
totdepth
+=
depth
;
s
->
leaves
++
;
}
else
{
/*
* New tnode. Decend one level
/*
* New tnode. Decend one level
*/
s
->
tnodes
++
;
s
->
nodesizes
[
tn
->
bits
]
++
;
depth
++
;
n
=
tn
->
child
[
cindex
];
tn
=
(
struct
tnode
*
)
n
;
pend
=
tn
->
pos
+
tn
->
bits
;
...
...
@@ -2303,13 +2305,13 @@ static struct trie_stat *trie_collect_stats(struct trie *t)
}
else
{
cindex
++
;
s
->
nullpointers
++
;
s
->
nullpointers
++
;
}
/*
* Test if we are done
* Test if we are done
*/
while
(
cindex
>=
(
1
<<
tn
->
bits
))
{
/*
...
...
@@ -2317,7 +2319,7 @@ static struct trie_stat *trie_collect_stats(struct trie *t)
* pop off all traversed nodes
*/
if
(
NODE_PARENT
(
tn
)
==
NULL
)
{
tn
=
NULL
;
n
=
NULL
;
...
...
@@ -2326,9 +2328,9 @@ static struct trie_stat *trie_collect_stats(struct trie *t)
else
{
cindex
=
tkey_extract_bits
(
tn
->
key
,
NODE_PARENT
(
tn
)
->
pos
,
NODE_PARENT
(
tn
)
->
bits
);
tn
=
NODE_PARENT
(
tn
);
cindex
++
;
cindex
++
;
n
=
(
struct
node
*
)
tn
;
pend
=
tn
->
pos
+
tn
->
bits
;
pend
=
tn
->
pos
+
tn
->
bits
;
indent
-=
3
;
depth
--
;
}
...
...
@@ -2339,7 +2341,7 @@ static struct trie_stat *trie_collect_stats(struct trie *t)
}
}
read_unlock
(
&
fib_lock
);
read_unlock
(
&
fib_lock
);
return
s
;
}
...
...
@@ -2375,7 +2377,7 @@ static void fib_triestat_seq_stop(struct seq_file *seq, void *v)
}
/*
/*
* This outputs /proc/net/fib_triestats
*
* It always works in backward compatibility mode.
...
...
@@ -2401,7 +2403,7 @@ static void collect_and_show(struct trie *t, struct seq_file *seq)
avdepth
=
0
;
seq_printf
(
seq
,
"Aver depth: %d.%02d
\n
"
,
avdepth
/
100
,
avdepth
%
100
);
seq_printf
(
seq
,
"Max depth: %4d
\n
"
,
stat
->
maxdepth
);
seq_printf
(
seq
,
"Leaves: %d
\n
"
,
stat
->
leaves
);
bytes
+=
sizeof
(
struct
leaf
)
*
stat
->
leaves
;
seq_printf
(
seq
,
"Internal nodes: %d
\n
"
,
stat
->
tnodes
);
...
...
@@ -2413,7 +2415,7 @@ static void collect_and_show(struct trie *t, struct seq_file *seq)
max
--
;
pointers
=
0
;
for
(
i
=
1
;
i
<=
max
;
i
++
)
for
(
i
=
1
;
i
<=
max
;
i
++
)
if
(
stat
->
nodesizes
[
i
]
!=
0
)
{
seq_printf
(
seq
,
" %d: %d"
,
i
,
stat
->
nodesizes
[
i
]);
pointers
+=
(
1
<<
i
)
*
stat
->
nodesizes
[
i
];
...
...
@@ -2444,30 +2446,30 @@ static void collect_and_show(struct trie *t, struct seq_file *seq)
static
int
fib_triestat_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
char
bf
[
128
];
if
(
v
==
SEQ_START_TOKEN
)
{
seq_printf
(
seq
,
"Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.
\n
"
,
seq_printf
(
seq
,
"Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.
\n
"
,
sizeof
(
struct
leaf
),
sizeof
(
struct
tnode
));
if
(
trie_local
)
if
(
trie_local
)
collect_and_show
(
trie_local
,
seq
);
if
(
trie_main
)
if
(
trie_main
)
collect_and_show
(
trie_main
,
seq
);
}
else
{
snprintf
(
bf
,
sizeof
(
bf
),
"*
\t
%08X
\t
%08X"
,
200
,
400
);
seq_printf
(
seq
,
"%-127s
\n
"
,
bf
);
}
return
0
;
}
static
struct
seq_operations
fib_triestat_seq_ops
=
{
.
start
=
fib_triestat_seq_start
,
.
next
=
fib_triestat_seq_next
,
.
stop
=
fib_triestat_seq_stop
,
.
show
=
fib_triestat_seq_show
,
.
start
=
fib_triestat_seq_start
,
.
next
=
fib_triestat_seq_next
,
.
stop
=
fib_triestat_seq_stop
,
.
show
=
fib_triestat_seq_show
,
};
static
int
fib_triestat_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
...
...
@@ -2479,7 +2481,7 @@ static int fib_triestat_seq_open(struct inode *inode, struct file *file)
if
(
rc
)
goto
out_kfree
;
seq
=
file
->
private_data
;
seq
=
file
->
private_data
;
out:
return
rc
;
out_kfree:
...
...
@@ -2487,11 +2489,11 @@ static int fib_triestat_seq_open(struct inode *inode, struct file *file)
}
static
struct
file_operations
fib_triestat_seq_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
fib_triestat_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release_private
,
.
owner
=
THIS_MODULE
,
.
open
=
fib_triestat_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release_private
,
};
int
__init
fib_stat_proc_init
(
void
)
...
...
@@ -2536,7 +2538,7 @@ static void fib_trie_seq_stop(struct seq_file *seq, void *v)
}
/*
/*
* This outputs /proc/net/fib_trie.
*
* It always works in backward compatibility mode.
...
...
@@ -2548,10 +2550,10 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
char
bf
[
128
];
if
(
v
==
SEQ_START_TOKEN
)
{
if
(
trie_local
)
if
(
trie_local
)
trie_dump_seq
(
seq
,
trie_local
);
if
(
trie_main
)
if
(
trie_main
)
trie_dump_seq
(
seq
,
trie_main
);
}
...
...
@@ -2565,10 +2567,10 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
}
static
struct
seq_operations
fib_trie_seq_ops
=
{
.
start
=
fib_trie_seq_start
,
.
next
=
fib_trie_seq_next
,
.
stop
=
fib_trie_seq_stop
,
.
show
=
fib_trie_seq_show
,
.
start
=
fib_trie_seq_start
,
.
next
=
fib_trie_seq_next
,
.
stop
=
fib_trie_seq_stop
,
.
show
=
fib_trie_seq_show
,
};
static
int
fib_trie_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
...
...
@@ -2580,7 +2582,7 @@ static int fib_trie_seq_open(struct inode *inode, struct file *file)
if
(
rc
)
goto
out_kfree
;
seq
=
file
->
private_data
;
seq
=
file
->
private_data
;
out:
return
rc
;
out_kfree:
...
...
@@ -2588,11 +2590,11 @@ static int fib_trie_seq_open(struct inode *inode, struct file *file)
}
static
struct
file_operations
fib_trie_seq_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
fib_trie_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release_private
,
.
owner
=
THIS_MODULE
,
.
open
=
fib_trie_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release_private
,
};
int
__init
fib_proc_init
(
void
)
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/ipip.c
浏览文件 @
38afd6ad
...
...
@@ -273,7 +273,7 @@ static void ipip_tunnel_uninit(struct net_device *dev)
dev_put
(
dev
);
}
static
void
ipip_err
(
struct
sk_buff
*
skb
,
void
*
__unused
)
static
void
ipip_err
(
struct
sk_buff
*
skb
,
u32
info
)
{
#ifndef I_WISH_WORLD_WERE_PERFECT
...
...
@@ -852,11 +852,39 @@ static int __init ipip_fb_tunnel_init(struct net_device *dev)
return
0
;
}
#ifdef CONFIG_INET_TUNNEL
static
struct
xfrm_tunnel
ipip_handler
=
{
.
handler
=
ipip_rcv
,
.
err_handler
=
ipip_err
,
};
static
inline
int
ipip_register
(
void
)
{
return
xfrm4_tunnel_register
(
&
ipip_handler
);
}
static
inline
int
ipip_unregister
(
void
)
{
return
xfrm4_tunnel_deregister
(
&
ipip_handler
);
}
#else
static
struct
net_protocol
ipip_protocol
=
{
.
handler
=
ipip_rcv
,
.
err_handler
=
ipip_err
,
.
no_policy
=
1
,
};
static
inline
int
ipip_register
(
void
)
{
return
inet_add_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
);
}
static
inline
int
ipip_unregister
(
void
)
{
return
inet_del_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
);
}
#endif
static
char
banner
[]
__initdata
=
KERN_INFO
"IPv4 over IPv4 tunneling driver
\n
"
;
...
...
@@ -866,7 +894,7 @@ static int __init ipip_init(void)
printk
(
banner
);
if
(
xfrm4_tunnel_register
(
&
ipip_handler
)
<
0
)
{
if
(
ipip_register
(
)
<
0
)
{
printk
(
KERN_INFO
"ipip init: can't register tunnel
\n
"
);
return
-
EAGAIN
;
}
...
...
@@ -888,13 +916,13 @@ static int __init ipip_init(void)
err2:
free_netdev
(
ipip_fb_tunnel_dev
);
err1:
xfrm4_tunnel_deregister
(
&
ipip_handler
);
ipip_unregister
(
);
goto
out
;
}
static
void
__exit
ipip_fini
(
void
)
{
if
(
xfrm4_tunnel_deregister
(
&
ipip_handler
)
<
0
)
if
(
ipip_unregister
(
)
<
0
)
printk
(
KERN_INFO
"ipip close: can't deregister tunnel
\n
"
);
unregister_netdev
(
ipip_fb_tunnel_dev
);
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_conntrack_amanda.c
浏览文件 @
38afd6ad
...
...
@@ -101,14 +101,13 @@ static int help(struct sk_buff **pskb,
if
(
port
==
0
||
len
>
5
)
break
;
exp
=
ip_conntrack_expect_alloc
();
exp
=
ip_conntrack_expect_alloc
(
ct
);
if
(
exp
==
NULL
)
{
ret
=
NF_DROP
;
goto
out
;
}
exp
->
expectfn
=
NULL
;
exp
->
master
=
ct
;
exp
->
tuple
.
src
.
ip
=
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
.
src
.
ip
;
exp
->
tuple
.
src
.
u
.
tcp
.
port
=
0
;
...
...
@@ -126,10 +125,9 @@ static int help(struct sk_buff **pskb,
ret
=
ip_nat_amanda_hook
(
pskb
,
ctinfo
,
tmp
-
amanda_buffer
,
len
,
exp
);
else
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
{
ip_conntrack_expect_free
(
exp
);
else
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
ret
=
NF_DROP
;
}
ip_conntrack_expect_put
(
exp
);
}
out:
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_conntrack_core.c
浏览文件 @
38afd6ad
...
...
@@ -137,19 +137,12 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse,
/* ip_conntrack_expect helper functions */
static
void
destroy_expect
(
struct
ip_conntrack_expect
*
exp
)
{
ip_conntrack_put
(
exp
->
master
);
IP_NF_ASSERT
(
!
timer_pending
(
&
exp
->
timeout
));
kmem_cache_free
(
ip_conntrack_expect_cachep
,
exp
);
CONNTRACK_STAT_INC
(
expect_delete
);
}
static
void
unlink_expect
(
struct
ip_conntrack_expect
*
exp
)
{
ASSERT_WRITE_LOCK
(
&
ip_conntrack_lock
);
IP_NF_ASSERT
(
!
timer_pending
(
&
exp
->
timeout
));
list_del
(
&
exp
->
list
);
/* Logically in destroy_expect, but we hold the lock here. */
CONNTRACK_STAT_INC
(
expect_delete
);
exp
->
master
->
expecting
--
;
}
...
...
@@ -160,7 +153,7 @@ static void expectation_timed_out(unsigned long ul_expect)
write_lock_bh
(
&
ip_conntrack_lock
);
unlink_expect
(
exp
);
write_unlock_bh
(
&
ip_conntrack_lock
);
destroy_expec
t
(
exp
);
ip_conntrack_expect_pu
t
(
exp
);
}
/* If an expectation for this connection is found, it gets delete from
...
...
@@ -198,7 +191,7 @@ static void remove_expectations(struct ip_conntrack *ct)
list_for_each_entry_safe
(
i
,
tmp
,
&
ip_conntrack_expect_list
,
list
)
{
if
(
i
->
master
==
ct
&&
del_timer
(
&
i
->
timeout
))
{
unlink_expect
(
i
);
destroy_expec
t
(
i
);
ip_conntrack_expect_pu
t
(
i
);
}
}
}
...
...
@@ -537,7 +530,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
if
(
exp
)
{
if
(
exp
->
expectfn
)
exp
->
expectfn
(
conntrack
,
exp
);
destroy_expec
t
(
exp
);
ip_conntrack_expect_pu
t
(
exp
);
}
return
&
conntrack
->
tuplehash
[
IP_CT_DIR_ORIGINAL
];
...
...
@@ -729,14 +722,14 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
if
(
expect_matches
(
i
,
exp
)
&&
del_timer
(
&
i
->
timeout
))
{
unlink_expect
(
i
);
write_unlock_bh
(
&
ip_conntrack_lock
);
destroy_expec
t
(
i
);
ip_conntrack_expect_pu
t
(
i
);
return
;
}
}
write_unlock_bh
(
&
ip_conntrack_lock
);
}
struct
ip_conntrack_expect
*
ip_conntrack_expect_alloc
(
void
)
struct
ip_conntrack_expect
*
ip_conntrack_expect_alloc
(
struct
ip_conntrack
*
me
)
{
struct
ip_conntrack_expect
*
new
;
...
...
@@ -745,18 +738,23 @@ struct ip_conntrack_expect *ip_conntrack_expect_alloc(void)
DEBUGP
(
"expect_related: OOM allocating expect
\n
"
);
return
NULL
;
}
new
->
master
=
NULL
;
new
->
master
=
me
;
atomic_inc
(
&
new
->
master
->
ct_general
.
use
);
atomic_set
(
&
new
->
use
,
1
);
return
new
;
}
void
ip_conntrack_expect_
free
(
struct
ip_conntrack_expect
*
expect
)
void
ip_conntrack_expect_
put
(
struct
ip_conntrack_expect
*
exp
)
{
kmem_cache_free
(
ip_conntrack_expect_cachep
,
expect
);
if
(
atomic_dec_and_test
(
&
exp
->
use
))
{
ip_conntrack_put
(
exp
->
master
);
kmem_cache_free
(
ip_conntrack_expect_cachep
,
exp
);
}
}
static
void
ip_conntrack_expect_insert
(
struct
ip_conntrack_expect
*
exp
)
{
atomic_inc
(
&
exp
->
master
->
ct_general
.
use
);
atomic_inc
(
&
exp
->
use
);
exp
->
master
->
expecting
++
;
list_add
(
&
exp
->
list
,
&
ip_conntrack_expect_list
);
...
...
@@ -778,7 +776,7 @@ static void evict_oldest_expect(struct ip_conntrack *master)
if
(
i
->
master
==
master
)
{
if
(
del_timer
(
&
i
->
timeout
))
{
unlink_expect
(
i
);
destroy_expec
t
(
i
);
ip_conntrack_expect_pu
t
(
i
);
}
break
;
}
...
...
@@ -810,8 +808,6 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
/* Refresh timer: if it's dying, ignore.. */
if
(
refresh_timer
(
i
))
{
ret
=
0
;
/* We don't need the one they've given us. */
ip_conntrack_expect_free
(
expect
);
goto
out
;
}
}
else
if
(
expect_clash
(
i
,
expect
))
{
...
...
@@ -881,7 +877,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
list_for_each_entry_safe
(
exp
,
tmp
,
&
ip_conntrack_expect_list
,
list
)
{
if
(
exp
->
master
->
helper
==
me
&&
del_timer
(
&
exp
->
timeout
))
{
unlink_expect
(
exp
);
destroy_expec
t
(
exp
);
ip_conntrack_expect_pu
t
(
exp
);
}
}
/* Get rid of expecteds, set helpers to NULL. */
...
...
@@ -1111,6 +1107,9 @@ void ip_conntrack_cleanup(void)
schedule
();
goto
i_see_dead_people
;
}
/* wait until all references to ip_conntrack_untracked are dropped */
while
(
atomic_read
(
&
ip_conntrack_untracked
.
ct_general
.
use
)
>
1
)
schedule
();
kmem_cache_destroy
(
ip_conntrack_cachep
);
kmem_cache_destroy
(
ip_conntrack_expect_cachep
);
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_conntrack_ftp.c
浏览文件 @
38afd6ad
...
...
@@ -376,7 +376,7 @@ static int help(struct sk_buff **pskb,
fb_ptr
+
matchoff
,
matchlen
,
ntohl
(
th
->
seq
)
+
matchoff
);
/* Allocate expectation which will be inserted */
exp
=
ip_conntrack_expect_alloc
();
exp
=
ip_conntrack_expect_alloc
(
ct
);
if
(
exp
==
NULL
)
{
ret
=
NF_DROP
;
goto
out
;
...
...
@@ -403,8 +403,7 @@ static int help(struct sk_buff **pskb,
networks, or the packet filter itself). */
if
(
!
loose
)
{
ret
=
NF_ACCEPT
;
ip_conntrack_expect_free
(
exp
);
goto
out_update_nl
;
goto
out_put_expect
;
}
exp
->
tuple
.
dst
.
ip
=
htonl
((
array
[
0
]
<<
24
)
|
(
array
[
1
]
<<
16
)
|
(
array
[
2
]
<<
8
)
|
array
[
3
]);
...
...
@@ -419,7 +418,6 @@ static int help(struct sk_buff **pskb,
{
0xFFFFFFFF
,
{
.
tcp
=
{
0xFFFF
}
},
0xFF
}});
exp
->
expectfn
=
NULL
;
exp
->
master
=
ct
;
/* Now, NAT might want to mangle the packet, and register the
* (possibly changed) expectation itself. */
...
...
@@ -428,13 +426,15 @@ static int help(struct sk_buff **pskb,
matchoff
,
matchlen
,
exp
,
&
seq
);
else
{
/* Can't expect this? Best to drop packet now. */
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
{
ip_conntrack_expect_free
(
exp
);
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
ret
=
NF_DROP
;
}
else
else
ret
=
NF_ACCEPT
;
}
out_put_expect:
ip_conntrack_expect_put
(
exp
);
out_update_nl:
/* Now if this ends in \n, update ftp info. Seq may have been
* adjusted by NAT code. */
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_conntrack_irc.c
浏览文件 @
38afd6ad
...
...
@@ -197,7 +197,7 @@ static int help(struct sk_buff **pskb,
continue
;
}
exp
=
ip_conntrack_expect_alloc
();
exp
=
ip_conntrack_expect_alloc
(
ct
);
if
(
exp
==
NULL
)
{
ret
=
NF_DROP
;
goto
out
;
...
...
@@ -221,16 +221,14 @@ static int help(struct sk_buff **pskb,
{
{
0
,
{
0
}
},
{
0xFFFFFFFF
,
{
.
tcp
=
{
0xFFFF
}
},
0xFF
}});
exp
->
expectfn
=
NULL
;
exp
->
master
=
ct
;
if
(
ip_nat_irc_hook
)
ret
=
ip_nat_irc_hook
(
pskb
,
ctinfo
,
addr_beg_p
-
ib_ptr
,
addr_end_p
-
addr_beg_p
,
exp
);
else
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
{
ip_conntrack_expect_free
(
exp
);
else
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
ret
=
NF_DROP
;
}
ip_conntrack_expect_put
(
exp
);
goto
out
;
}
/* for .. NUM_DCCPROTO */
}
/* while data < ... */
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_conntrack_standalone.c
浏览文件 @
38afd6ad
...
...
@@ -985,7 +985,7 @@ EXPORT_SYMBOL(ip_ct_refresh_acct);
EXPORT_SYMBOL
(
ip_ct_protos
);
EXPORT_SYMBOL
(
ip_ct_find_proto
);
EXPORT_SYMBOL
(
ip_conntrack_expect_alloc
);
EXPORT_SYMBOL
(
ip_conntrack_expect_
free
);
EXPORT_SYMBOL
(
ip_conntrack_expect_
put
);
EXPORT_SYMBOL
(
ip_conntrack_expect_related
);
EXPORT_SYMBOL
(
ip_conntrack_unexpect_related
);
EXPORT_SYMBOL
(
ip_conntrack_tuple_taken
);
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_conntrack_tftp.c
浏览文件 @
38afd6ad
...
...
@@ -65,7 +65,7 @@ static int tftp_help(struct sk_buff **pskb,
DUMP_TUPLE
(
&
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
);
DUMP_TUPLE
(
&
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
);
exp
=
ip_conntrack_expect_alloc
();
exp
=
ip_conntrack_expect_alloc
(
ct
);
if
(
exp
==
NULL
)
return
NF_DROP
;
...
...
@@ -75,17 +75,15 @@ static int tftp_help(struct sk_buff **pskb,
exp
->
mask
.
dst
.
u
.
udp
.
port
=
0xffff
;
exp
->
mask
.
dst
.
protonum
=
0xff
;
exp
->
expectfn
=
NULL
;
exp
->
master
=
ct
;
DEBUGP
(
"expect: "
);
DUMP_TUPLE
(
&
exp
->
tuple
);
DUMP_TUPLE
(
&
exp
->
mask
);
if
(
ip_nat_tftp_hook
)
ret
=
ip_nat_tftp_hook
(
pskb
,
ctinfo
,
exp
);
else
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
{
ip_conntrack_expect_free
(
exp
);
else
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
ret
=
NF_DROP
;
}
ip_conntrack_expect_put
(
exp
);
break
;
case
TFTP_OPCODE_DATA
:
case
TFTP_OPCODE_ACK
:
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_nat_amanda.c
浏览文件 @
38afd6ad
...
...
@@ -56,10 +56,8 @@ static unsigned int help(struct sk_buff **pskb,
break
;
}
if
(
port
==
0
)
{
ip_conntrack_expect_free
(
exp
);
if
(
port
==
0
)
return
NF_DROP
;
}
sprintf
(
buffer
,
"%u"
,
port
);
ret
=
ip_nat_mangle_udp_packet
(
pskb
,
exp
->
master
,
ctinfo
,
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_nat_ftp.c
浏览文件 @
38afd6ad
...
...
@@ -143,10 +143,8 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb,
break
;
}
if
(
port
==
0
)
{
ip_conntrack_expect_free
(
exp
);
if
(
port
==
0
)
return
NF_DROP
;
}
if
(
!
mangle
[
type
](
pskb
,
newip
,
port
,
matchoff
,
matchlen
,
ct
,
ctinfo
,
seq
))
{
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_nat_irc.c
浏览文件 @
38afd6ad
...
...
@@ -65,10 +65,8 @@ static unsigned int help(struct sk_buff **pskb,
break
;
}
if
(
port
==
0
)
{
ip_conntrack_expect_free
(
exp
);
if
(
port
==
0
)
return
NF_DROP
;
}
/* strlen("\1DCC CHAT chat AAAAAAAA P\1\n")=27
* strlen("\1DCC SCHAT chat AAAAAAAA P\1\n")=28
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_nat_proto_icmp.c
浏览文件 @
38afd6ad
...
...
@@ -35,16 +35,17 @@ icmp_unique_tuple(struct ip_conntrack_tuple *tuple,
const
struct
ip_conntrack
*
conntrack
)
{
static
u_int16_t
id
;
unsigned
int
range_size
=
(
unsigned
int
)
range
->
max
.
icmp
.
id
-
range
->
min
.
icmp
.
id
+
1
;
unsigned
int
range_size
;
unsigned
int
i
;
range_size
=
ntohs
(
range
->
max
.
icmp
.
id
)
-
ntohs
(
range
->
min
.
icmp
.
id
)
+
1
;
/* If no range specified... */
if
(
!
(
range
->
flags
&
IP_NAT_RANGE_PROTO_SPECIFIED
))
range_size
=
0xFFFF
;
for
(
i
=
0
;
i
<
range_size
;
i
++
,
id
++
)
{
tuple
->
src
.
u
.
icmp
.
id
=
range
->
min
.
icmp
.
id
+
(
id
%
range_size
);
tuple
->
src
.
u
.
icmp
.
id
=
htons
(
ntohs
(
range
->
min
.
icmp
.
id
)
+
(
id
%
range_size
));
if
(
!
ip_nat_used_tuple
(
tuple
,
conntrack
))
return
1
;
}
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_nat_proto_tcp.c
浏览文件 @
38afd6ad
...
...
@@ -40,7 +40,8 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple,
enum
ip_nat_manip_type
maniptype
,
const
struct
ip_conntrack
*
conntrack
)
{
static
u_int16_t
port
,
*
portptr
;
static
u_int16_t
port
;
u_int16_t
*
portptr
;
unsigned
int
range_size
,
min
,
i
;
if
(
maniptype
==
IP_NAT_MANIP_SRC
)
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_nat_proto_udp.c
浏览文件 @
38afd6ad
...
...
@@ -41,7 +41,8 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple,
enum
ip_nat_manip_type
maniptype
,
const
struct
ip_conntrack
*
conntrack
)
{
static
u_int16_t
port
,
*
portptr
;
static
u_int16_t
port
;
u_int16_t
*
portptr
;
unsigned
int
range_size
,
min
,
i
;
if
(
maniptype
==
IP_NAT_MANIP_SRC
)
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/netfilter/ip_nat_tftp.c
浏览文件 @
38afd6ad
...
...
@@ -45,10 +45,8 @@ static unsigned int help(struct sk_buff **pskb,
exp
->
saved_proto
.
udp
.
port
=
exp
->
tuple
.
dst
.
u
.
tcp
.
port
;
exp
->
dir
=
IP_CT_DIR_REPLY
;
exp
->
expectfn
=
ip_nat_follow_master
;
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
{
ip_conntrack_expect_free
(
exp
);
if
(
ip_conntrack_expect_related
(
exp
)
!=
0
)
return
NF_DROP
;
}
return
NF_ACCEPT
;
}
...
...
This diff is collapsed.
Click to expand it.
net/ipv4/xfrm4_tunnel.c
浏览文件 @
38afd6ad
...
...
@@ -78,10 +78,9 @@ static int ipip_rcv(struct sk_buff *skb)
static
void
ipip_err
(
struct
sk_buff
*
skb
,
u32
info
)
{
struct
xfrm_tunnel
*
handler
=
ipip_handler
;
u32
arg
=
info
;
if
(
handler
)
handler
->
err_handler
(
skb
,
&
arg
);
handler
->
err_handler
(
skb
,
info
);
}
static
int
ipip_init_state
(
struct
xfrm_state
*
x
)
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/Kconfig
浏览文件 @
38afd6ad
...
...
@@ -91,7 +91,6 @@ config INET6_TUNNEL
config IPV6_TUNNEL
tristate "IPv6: IPv6-in-IPv6 tunnel"
depends on IPV6
select INET6_TUNNEL
---help---
Support for IPv6-in-IPv6 tunnels described in RFC 2473.
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/ip6_tunnel.c
浏览文件 @
38afd6ad
...
...
@@ -1110,11 +1110,39 @@ ip6ip6_fb_tnl_dev_init(struct net_device *dev)
return
0
;
}
#ifdef CONFIG_INET6_TUNNEL
static
struct
xfrm6_tunnel
ip6ip6_handler
=
{
.
handler
=
ip6ip6_rcv
,
.
err_handler
=
ip6ip6_err
,
.
handler
=
ip6ip6_rcv
,
.
err_handler
=
ip6ip6_err
,
};
static
inline
int
ip6ip6_register
(
void
)
{
return
xfrm6_tunnel_register
(
&
ip6ip6_handler
);
}
static
inline
int
ip6ip6_unregister
(
void
)
{
return
xfrm6_tunnel_unregister
(
&
ip6ip6_handler
);
}
#else
static
struct
inet6_protocol
xfrm6_tunnel_protocol
=
{
.
handler
=
ip6ip6_rcv
,
.
err_handler
=
ip6ip6_err
,
.
flags
=
INET6_PROTO_NOPOLICY
|
INET6_PROTO_FINAL
,
};
static
inline
int
ip6ip6_register
(
void
)
{
return
inet6_add_protocol
(
&
xfrm6_tunnel_protocol
,
IPPROTO_IPV6
);
}
static
inline
int
ip6ip6_unregister
(
void
)
{
return
inet6_del_protocol
(
&
xfrm6_tunnel_protocol
,
IPPROTO_IPV6
);
}
#endif
/**
* ip6_tunnel_init - register protocol and reserve needed resources
*
...
...
@@ -1125,7 +1153,7 @@ static int __init ip6_tunnel_init(void)
{
int
err
;
if
(
xfrm6_tunnel_register
(
&
ip6ip6_handler
)
<
0
)
{
if
(
ip6ip6_register
(
)
<
0
)
{
printk
(
KERN_ERR
"ip6ip6 init: can't register tunnel
\n
"
);
return
-
EAGAIN
;
}
...
...
@@ -1144,7 +1172,7 @@ static int __init ip6_tunnel_init(void)
}
return
0
;
fail:
xfrm6_tunnel_deregister
(
&
ip6ip6_handler
);
ip6ip6_unregister
(
);
return
err
;
}
...
...
@@ -1154,7 +1182,7 @@ static int __init ip6_tunnel_init(void)
static
void
__exit
ip6_tunnel_cleanup
(
void
)
{
if
(
xfrm6_tunnel_deregister
(
&
ip6ip6_handler
)
<
0
)
if
(
ip6ip6_unregister
(
)
<
0
)
printk
(
KERN_INFO
"ip6ip6 close: can't deregister tunnel
\n
"
);
unregister_netdev
(
ip6ip6_fb_tnl_dev
);
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6_queue.c
浏览文件 @
38afd6ad
...
...
@@ -76,7 +76,9 @@ static DECLARE_MUTEX(ipqnl_sem);
static
void
ipq_issue_verdict
(
struct
ipq_queue_entry
*
entry
,
int
verdict
)
{
local_bh_disable
();
nf_reinject
(
entry
->
skb
,
entry
->
info
,
verdict
);
local_bh_enable
();
kfree
(
entry
);
}
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6t_LOG.c
浏览文件 @
38afd6ad
...
...
@@ -373,9 +373,10 @@ ip6t_log_packet(unsigned int hooknum,
in
?
in
->
name
:
""
,
out
?
out
->
name
:
""
);
if
(
in
&&
!
out
)
{
unsigned
int
len
;
/* MAC logging for input chain only. */
printk
(
"MAC="
);
if
(
skb
->
dev
&&
skb
->
dev
->
hard_header_len
&&
if
(
skb
->
dev
&&
(
len
=
skb
->
dev
->
hard_header_len
)
&&
skb
->
mac
.
raw
!=
skb
->
nh
.
raw
)
{
unsigned
char
*
p
=
skb
->
mac
.
raw
;
int
i
;
...
...
@@ -384,9 +385,11 @@ ip6t_log_packet(unsigned int hooknum,
(
p
-=
ETH_HLEN
)
<
skb
->
head
)
p
=
NULL
;
if
(
p
!=
NULL
)
for
(
i
=
0
;
i
<
skb
->
dev
->
hard_header_len
;
i
++
)
printk
(
"%02x"
,
p
[
i
]);
if
(
p
!=
NULL
)
{
for
(
i
=
0
;
i
<
len
;
i
++
)
printk
(
"%02x%s"
,
p
[
i
],
i
==
len
-
1
?
""
:
":"
);
}
printk
(
" "
);
if
(
skb
->
dev
->
type
==
ARPHRD_SIT
)
{
...
...
This diff is collapsed.
Click to expand it.
net/netlink/af_netlink.c
浏览文件 @
38afd6ad
...
...
@@ -648,7 +648,8 @@ void netlink_detachskb(struct sock *sk, struct sk_buff *skb)
sock_put
(
sk
);
}
static
inline
struct
sk_buff
*
netlink_trim
(
struct
sk_buff
*
skb
,
int
allocation
)
static
inline
struct
sk_buff
*
netlink_trim
(
struct
sk_buff
*
skb
,
unsigned
int
__nocast
allocation
)
{
int
delta
;
...
...
@@ -717,7 +718,7 @@ struct netlink_broadcast_data {
int
failure
;
int
congested
;
int
delivered
;
int
allocation
;
unsigned
int
allocation
;
struct
sk_buff
*
skb
,
*
skb2
;
};
...
...
This diff is collapsed.
Click to expand it.
net/sched/em_meta.c
浏览文件 @
38afd6ad
...
...
@@ -27,17 +27,17 @@
* lvalue rvalue
* +-----------+ +-----------+
* | type: INT | | type: INT |
* def | id:
INDEV
| | id: VALUE |
* def | id:
DEV
| | id: VALUE |
* | data: | | data: 3 |
* +-----------+ +-----------+
* | |
* ---> meta_ops[INT][
INDEV](...)
|
* ---> meta_ops[INT][
DEV](...)
|
* | |
* ----------- |
* V V
* +-----------+ +-----------+
* | type: INT | | type: INT |
* obj | id:
INDEV |
| id: VALUE |
* obj | id:
DEV |
| id: VALUE |
* | data: 2 |<--data got filled out | data: 3 |
* +-----------+ +-----------+
* | |
...
...
@@ -170,26 +170,6 @@ META_COLLECTOR(var_dev)
*
err
=
var_dev
(
skb
->
dev
,
dst
);
}
META_COLLECTOR
(
int_indev
)
{
*
err
=
int_dev
(
skb
->
input_dev
,
dst
);
}
META_COLLECTOR
(
var_indev
)
{
*
err
=
var_dev
(
skb
->
input_dev
,
dst
);
}
META_COLLECTOR
(
int_realdev
)
{
*
err
=
int_dev
(
skb
->
real_dev
,
dst
);
}
META_COLLECTOR
(
var_realdev
)
{
*
err
=
var_dev
(
skb
->
real_dev
,
dst
);
}
/**************************************************************************
* skb attributes
**************************************************************************/
...
...
@@ -245,18 +225,6 @@ META_COLLECTOR(int_tcindex)
dst
->
value
=
skb
->
tc_index
;
}
#ifdef CONFIG_NET_CLS_ACT
META_COLLECTOR
(
int_tcverd
)
{
dst
->
value
=
skb
->
tc_verd
;
}
META_COLLECTOR
(
int_tcclassid
)
{
dst
->
value
=
skb
->
tc_classid
;
}
#endif
/**************************************************************************
* Routing
**************************************************************************/
...
...
@@ -505,8 +473,6 @@ struct meta_ops
static
struct
meta_ops
__meta_ops
[
TCF_META_TYPE_MAX
+
1
][
TCF_META_ID_MAX
+
1
]
=
{
[
TCF_META_TYPE_VAR
]
=
{
[
META_ID
(
DEV
)]
=
META_FUNC
(
var_dev
),
[
META_ID
(
INDEV
)]
=
META_FUNC
(
var_indev
),
[
META_ID
(
REALDEV
)]
=
META_FUNC
(
var_realdev
),
[
META_ID
(
SK_BOUND_IF
)]
=
META_FUNC
(
var_sk_bound_if
),
},
[
TCF_META_TYPE_INT
]
=
{
...
...
@@ -515,8 +481,6 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
[
META_ID
(
LOADAVG_1
)]
=
META_FUNC
(
int_loadavg_1
),
[
META_ID
(
LOADAVG_2
)]
=
META_FUNC
(
int_loadavg_2
),
[
META_ID
(
DEV
)]
=
META_FUNC
(
int_dev
),
[
META_ID
(
INDEV
)]
=
META_FUNC
(
int_indev
),
[
META_ID
(
REALDEV
)]
=
META_FUNC
(
int_realdev
),
[
META_ID
(
PRIORITY
)]
=
META_FUNC
(
int_priority
),
[
META_ID
(
PROTOCOL
)]
=
META_FUNC
(
int_protocol
),
[
META_ID
(
PKTTYPE
)]
=
META_FUNC
(
int_pkttype
),
...
...
@@ -527,10 +491,6 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
[
META_ID
(
NFMARK
)]
=
META_FUNC
(
int_nfmark
),
#endif
[
META_ID
(
TCINDEX
)]
=
META_FUNC
(
int_tcindex
),
#ifdef CONFIG_NET_CLS_ACT
[
META_ID
(
TCVERDICT
)]
=
META_FUNC
(
int_tcverd
),
[
META_ID
(
TCCLASSID
)]
=
META_FUNC
(
int_tcclassid
),
#endif
#ifdef CONFIG_NET_CLS_ROUTE
[
META_ID
(
RTCLASSID
)]
=
META_FUNC
(
int_rtclassid
),
#endif
...
...
This diff is collapsed.
Click to expand it.
net/sched/em_text.c
浏览文件 @
38afd6ad
...
...
@@ -55,9 +55,6 @@ static int em_text_change(struct tcf_proto *tp, void *data, int len,
struct
ts_config
*
ts_conf
;
int
flags
=
0
;
printk
(
"Configuring text: %s from %d:%d to %d:%d len %d
\n
"
,
conf
->
algo
,
conf
->
from_offset
,
conf
->
from_layer
,
conf
->
to_offset
,
conf
->
to_layer
,
conf
->
pattern_len
);
if
(
len
<
sizeof
(
*
conf
)
||
len
<
(
sizeof
(
*
conf
)
+
conf
->
pattern_len
))
return
-
EINVAL
;
...
...
This diff is collapsed.
Click to expand it.
net/sched/sch_generic.c
浏览文件 @
38afd6ad
...
...
@@ -331,11 +331,10 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
int
prio
;
struct
sk_buff_head
*
list
=
qdisc_priv
(
qdisc
);
for
(
prio
=
0
;
prio
<
PFIFO_FAST_BANDS
;
prio
++
,
list
++
)
{
struct
sk_buff
*
skb
=
__qdisc_dequeue_head
(
qdisc
,
list
);
if
(
skb
)
{
for
(
prio
=
0
;
prio
<
PFIFO_FAST_BANDS
;
prio
++
)
{
if
(
!
skb_queue_empty
(
list
+
prio
))
{
qdisc
->
q
.
qlen
--
;
return
skb
;
return
__qdisc_dequeue_head
(
qdisc
,
list
+
prio
)
;
}
}
...
...
This diff is collapsed.
Click to expand it.
net/sctp/input.c
浏览文件 @
38afd6ad
...
...
@@ -351,7 +351,6 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
*
*/
void
sctp_icmp_proto_unreachable
(
struct
sock
*
sk
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
t
)
{
...
...
@@ -367,7 +366,6 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
/* Common lookup code for icmp/icmpv6 error handler. */
struct
sock
*
sctp_err_lookup
(
int
family
,
struct
sk_buff
*
skb
,
struct
sctphdr
*
sctphdr
,
struct
sctp_endpoint
**
epp
,
struct
sctp_association
**
app
,
struct
sctp_transport
**
tpp
)
{
...
...
@@ -375,11 +373,10 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
union
sctp_addr
daddr
;
struct
sctp_af
*
af
;
struct
sock
*
sk
=
NULL
;
struct
sctp_endpoint
*
ep
=
NULL
;
struct
sctp_association
*
asoc
=
NULL
;
struct
sctp_transport
*
transport
=
NULL
;
*
app
=
NULL
;
*
epp
=
NULL
;
*
tpp
=
NULL
;
*
app
=
NULL
;
*
tpp
=
NULL
;
af
=
sctp_get_af_specific
(
family
);
if
(
unlikely
(
!
af
))
{
...
...
@@ -394,26 +391,15 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
* packet.
*/
asoc
=
__sctp_lookup_association
(
&
saddr
,
&
daddr
,
&
transport
);
if
(
!
asoc
)
{
/* If there is no matching association, see if it matches any
* endpoint. This may happen for an ICMP error generated in
* response to an INIT_ACK.
*/
ep
=
__sctp_rcv_lookup_endpoint
(
&
daddr
);
if
(
!
ep
)
{
return
NULL
;
}
}
if
(
!
asoc
)
return
NULL
;
if
(
asoc
)
{
sk
=
asoc
->
base
.
sk
;
sk
=
asoc
->
base
.
sk
;
if
(
ntohl
(
sctphdr
->
vtag
)
!=
asoc
->
c
.
peer_vtag
)
{
ICMP_INC_STATS_BH
(
ICMP_MIB_INERRORS
);
goto
out
;
}
}
else
sk
=
ep
->
base
.
sk
;
if
(
ntohl
(
sctphdr
->
vtag
)
!=
asoc
->
c
.
peer_vtag
)
{
ICMP_INC_STATS_BH
(
ICMP_MIB_INERRORS
);
goto
out
;
}
sctp_bh_lock_sock
(
sk
);
...
...
@@ -423,7 +409,6 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
if
(
sock_owned_by_user
(
sk
))
NET_INC_STATS_BH
(
LINUX_MIB_LOCKDROPPEDICMPS
);
*
epp
=
ep
;
*
app
=
asoc
;
*
tpp
=
transport
;
return
sk
;
...
...
@@ -432,21 +417,16 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
sock_put
(
sk
);
if
(
asoc
)
sctp_association_put
(
asoc
);
if
(
ep
)
sctp_endpoint_put
(
ep
);
return
NULL
;
}
/* Common cleanup code for icmp/icmpv6 error handler. */
void
sctp_err_finish
(
struct
sock
*
sk
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
)
void
sctp_err_finish
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
{
sctp_bh_unlock_sock
(
sk
);
sock_put
(
sk
);
if
(
asoc
)
sctp_association_put
(
asoc
);
if
(
ep
)
sctp_endpoint_put
(
ep
);
}
/*
...
...
@@ -471,7 +451,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
int
type
=
skb
->
h
.
icmph
->
type
;
int
code
=
skb
->
h
.
icmph
->
code
;
struct
sock
*
sk
;
struct
sctp_endpoint
*
ep
;
struct
sctp_association
*
asoc
;
struct
sctp_transport
*
transport
;
struct
inet_sock
*
inet
;
...
...
@@ -488,7 +467,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
savesctp
=
skb
->
h
.
raw
;
skb
->
nh
.
iph
=
iph
;
skb
->
h
.
raw
=
(
char
*
)
sh
;
sk
=
sctp_err_lookup
(
AF_INET
,
skb
,
sh
,
&
ep
,
&
asoc
,
&
transport
);
sk
=
sctp_err_lookup
(
AF_INET
,
skb
,
sh
,
&
asoc
,
&
transport
);
/* Put back, the original pointers. */
skb
->
nh
.
raw
=
saveip
;
skb
->
h
.
raw
=
savesctp
;
...
...
@@ -515,7 +494,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
}
else
{
if
(
ICMP_PROT_UNREACH
==
code
)
{
sctp_icmp_proto_unreachable
(
sk
,
ep
,
asoc
,
sctp_icmp_proto_unreachable
(
sk
,
asoc
,
transport
);
goto
out_unlock
;
}
...
...
@@ -544,7 +523,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
}
out_unlock:
sctp_err_finish
(
sk
,
ep
,
asoc
);
sctp_err_finish
(
sk
,
asoc
);
}
/*
...
...
This diff is collapsed.
Click to expand it.
net/sctp/ipv6.c
浏览文件 @
38afd6ad
...
...
@@ -91,7 +91,6 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct
ipv6hdr
*
iph
=
(
struct
ipv6hdr
*
)
skb
->
data
;
struct
sctphdr
*
sh
=
(
struct
sctphdr
*
)(
skb
->
data
+
offset
);
struct
sock
*
sk
;
struct
sctp_endpoint
*
ep
;
struct
sctp_association
*
asoc
;
struct
sctp_transport
*
transport
;
struct
ipv6_pinfo
*
np
;
...
...
@@ -105,7 +104,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
savesctp
=
skb
->
h
.
raw
;
skb
->
nh
.
ipv6h
=
iph
;
skb
->
h
.
raw
=
(
char
*
)
sh
;
sk
=
sctp_err_lookup
(
AF_INET6
,
skb
,
sh
,
&
ep
,
&
asoc
,
&
transport
);
sk
=
sctp_err_lookup
(
AF_INET6
,
skb
,
sh
,
&
asoc
,
&
transport
);
/* Put back, the original pointers. */
skb
->
nh
.
raw
=
saveip
;
skb
->
h
.
raw
=
savesctp
;
...
...
@@ -124,7 +123,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
goto
out_unlock
;
case
ICMPV6_PARAMPROB
:
if
(
ICMPV6_UNK_NEXTHDR
==
code
)
{
sctp_icmp_proto_unreachable
(
sk
,
ep
,
asoc
,
transport
);
sctp_icmp_proto_unreachable
(
sk
,
asoc
,
transport
);
goto
out_unlock
;
}
break
;
...
...
@@ -142,7 +141,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}
out_unlock:
sctp_err_finish
(
sk
,
ep
,
asoc
);
sctp_err_finish
(
sk
,
asoc
);
out:
if
(
likely
(
idev
!=
NULL
))
in6_dev_put
(
idev
);
...
...
This diff is collapsed.
Click to expand it.
net/sctp/objcnt.c
浏览文件 @
38afd6ad
...
...
@@ -127,8 +127,12 @@ static int sctp_dbg_objcnt_read(char *buffer, char **start, off_t offset,
/* Initialize the objcount in the proc filesystem. */
void
sctp_dbg_objcnt_init
(
void
)
{
create_proc_read_entry
(
"sctp_dbg_objcnt"
,
0
,
proc_net_sctp
,
struct
proc_dir_entry
*
ent
;
ent
=
create_proc_read_entry
(
"sctp_dbg_objcnt"
,
0
,
proc_net_sctp
,
sctp_dbg_objcnt_read
,
NULL
);
if
(
!
ent
)
printk
(
KERN_WARNING
"sctp_dbg_objcnt: Unable to create /proc entry.
\n
"
);
}
/* Cleanup the objcount entry in the proc filesystem. */
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部