Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
83a0e2be
Commit
83a0e2be
authored
Mar 23, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge nuts.ninka.net:/home/davem/src/BK/network-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
99447171
d786675f
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
203 additions
and
233 deletions
+203
-233
crypto/api.c
crypto/api.c
+1
-4
include/net/addrconf.h
include/net/addrconf.h
+3
-3
include/net/ipv6.h
include/net/ipv6.h
+7
-11
include/net/protocol.h
include/net/protocol.h
+1
-1
include/net/transp_v6.h
include/net/transp_v6.h
+8
-0
include/net/xfrm.h
include/net/xfrm.h
+1
-1
net/ipv6/addrconf.c
net/ipv6/addrconf.c
+34
-23
net/ipv6/af_inet6.c
net/ipv6/af_inet6.c
+7
-0
net/ipv6/exthdrs.c
net/ipv6/exthdrs.c
+93
-127
net/ipv6/icmp.c
net/ipv6/icmp.c
+3
-2
net/ipv6/ip6_input.c
net/ipv6/ip6_input.c
+8
-31
net/ipv6/reassembly.c
net/ipv6/reassembly.c
+29
-7
net/ipv6/tcp_ipv6.c
net/ipv6/tcp_ipv6.c
+2
-1
net/ipv6/udp.c
net/ipv6/udp.c
+2
-1
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_input.c
+4
-21
No files found.
crypto/api.c
View file @
83a0e2be
...
...
@@ -152,10 +152,7 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
void
crypto_free_tfm
(
struct
crypto_tfm
*
tfm
)
{
if
(
crypto_tfm_alg_type
(
tfm
)
==
CRYPTO_ALG_TYPE_CIPHER
)
if
(
tfm
->
crt_cipher
.
cit_iv
)
kfree
(
tfm
->
crt_cipher
.
cit_iv
);
crypto_exit_ops
(
tfm
);
crypto_alg_put
(
tfm
->
__crt_alg
);
kfree
(
tfm
);
}
...
...
include/net/addrconf.h
View file @
83a0e2be
...
...
@@ -175,7 +175,7 @@ extern void addrconf_forwarding_on(void);
* Hash function taken from net_alias.c
*/
static
__inline__
u8
ipv6_addr_hash
(
struct
in6_addr
*
addr
)
static
__inline__
u8
ipv6_addr_hash
(
const
struct
in6_addr
*
addr
)
{
__u32
word
;
...
...
@@ -195,7 +195,7 @@ static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr)
* compute link-local solicited-node multicast address
*/
static
inline
void
addrconf_addr_solict_mult
(
struct
in6_addr
*
addr
,
static
inline
void
addrconf_addr_solict_mult
(
const
struct
in6_addr
*
addr
,
struct
in6_addr
*
solicited
)
{
ipv6_addr_set
(
solicited
,
...
...
@@ -219,7 +219,7 @@ static inline void ipv6_addr_all_routers(struct in6_addr *addr)
__constant_htonl
(
0x2
));
}
static
inline
int
ipv6_addr_is_multicast
(
struct
in6_addr
*
addr
)
static
inline
int
ipv6_addr_is_multicast
(
const
struct
in6_addr
*
addr
)
{
return
(
addr
->
s6_addr32
[
0
]
&
__constant_htonl
(
0xFF000000
))
==
__constant_htonl
(
0xFF000000
);
}
...
...
include/net/ipv6.h
View file @
83a0e2be
...
...
@@ -203,12 +203,8 @@ extern int ip6_ra_control(struct sock *sk, int sel,
extern
int
ip6_call_ra_chain
(
struct
sk_buff
*
skb
,
int
sel
);
extern
int
ipv6_reassembly
(
struct
sk_buff
**
skb
,
int
);
extern
int
ipv6_parse_hopopts
(
struct
sk_buff
*
skb
,
int
);
extern
int
ipv6_parse_exthdrs
(
struct
sk_buff
**
skb
,
int
);
extern
struct
ipv6_txoptions
*
ipv6_dup_options
(
struct
sock
*
sk
,
struct
ipv6_txoptions
*
opt
);
extern
int
ip6_frag_nqueues
;
...
...
@@ -226,21 +222,21 @@ typedef int (*inet_getfrag_t) (const void *data,
unsigned
int
,
unsigned
int
);
extern
int
ipv6_addr_type
(
struct
in6_addr
*
addr
);
extern
int
ipv6_addr_type
(
const
struct
in6_addr
*
addr
);
static
inline
int
ipv6_addr_scope
(
struct
in6_addr
*
addr
)
static
inline
int
ipv6_addr_scope
(
const
struct
in6_addr
*
addr
)
{
return
ipv6_addr_type
(
addr
)
&
IPV6_ADDR_SCOPE_MASK
;
}
static
inline
int
ipv6_addr_cmp
(
struct
in6_addr
*
a1
,
struct
in6_addr
*
a2
)
static
inline
int
ipv6_addr_cmp
(
const
struct
in6_addr
*
a1
,
const
struct
in6_addr
*
a2
)
{
return
memcmp
((
void
*
)
a1
,
(
void
*
)
a2
,
sizeof
(
struct
in6_addr
));
return
memcmp
((
const
void
*
)
a1
,
(
const
void
*
)
a2
,
sizeof
(
struct
in6_addr
));
}
static
inline
void
ipv6_addr_copy
(
struct
in6_addr
*
a1
,
struct
in6_addr
*
a2
)
static
inline
void
ipv6_addr_copy
(
struct
in6_addr
*
a1
,
const
struct
in6_addr
*
a2
)
{
memcpy
((
void
*
)
a1
,
(
void
*
)
a2
,
sizeof
(
struct
in6_addr
));
memcpy
((
void
*
)
a1
,
(
const
void
*
)
a2
,
sizeof
(
struct
in6_addr
));
}
#ifndef __HAVE_ARCH_ADDR_SET
...
...
@@ -255,7 +251,7 @@ static inline void ipv6_addr_set(struct in6_addr *addr,
}
#endif
static
inline
int
ipv6_addr_any
(
struct
in6_addr
*
a
)
static
inline
int
ipv6_addr_any
(
const
struct
in6_addr
*
a
)
{
return
((
a
->
s6_addr32
[
0
]
|
a
->
s6_addr32
[
1
]
|
a
->
s6_addr32
[
2
]
|
a
->
s6_addr32
[
3
]
)
==
0
);
...
...
include/net/protocol.h
View file @
83a0e2be
...
...
@@ -44,7 +44,7 @@ struct inet_protocol
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct
inet6_protocol
{
int
(
*
handler
)(
struct
sk_buff
*
skb
);
int
(
*
handler
)(
struct
sk_buff
*
*
skbp
);
void
(
*
err_handler
)(
struct
sk_buff
*
skb
,
struct
inet6_skb_parm
*
opt
,
...
...
include/net/transp_v6.h
View file @
83a0e2be
...
...
@@ -15,6 +15,14 @@ extern struct proto tcpv6_prot;
struct
flowi
;
/* extention headers */
extern
void
ipv6_hopopts_init
(
void
);
extern
void
ipv6_rthdr_init
(
void
);
extern
void
ipv6_frag_init
(
void
);
extern
void
ipv6_nodata_init
(
void
);
extern
void
ipv6_destopt_init
(
void
);
/* transport protocols */
extern
void
rawv6_init
(
void
);
extern
void
udpv6_init
(
void
);
extern
void
tcpv6_init
(
void
);
...
...
include/net/xfrm.h
View file @
83a0e2be
...
...
@@ -730,7 +730,7 @@ extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
extern
void
xfrm_replay_advance
(
struct
xfrm_state
*
x
,
u32
seq
);
extern
int
xfrm_check_selectors
(
struct
xfrm_state
**
x
,
int
n
,
struct
flowi
*
fl
);
extern
int
xfrm4_rcv
(
struct
sk_buff
*
skb
);
extern
int
xfrm6_rcv
(
struct
sk_buff
*
skb
);
extern
int
xfrm6_rcv
(
struct
sk_buff
*
*
p
skb
);
extern
int
xfrm6_clear_mutable_options
(
struct
sk_buff
*
skb
,
u16
*
nh_offset
,
int
dir
);
extern
int
xfrm_user_policy
(
struct
sock
*
sk
,
int
optname
,
u8
*
optval
,
int
optlen
);
...
...
net/ipv6/addrconf.c
View file @
83a0e2be
...
...
@@ -97,6 +97,8 @@ static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpad
static
void
ipv6_regen_rndid
(
unsigned
long
data
);
static
int
desync_factor
=
MAX_DESYNC_FACTOR
*
HZ
;
static
struct
crypto_tfm
*
md5_tfm
;
static
spinlock_t
md5_tfm_lock
=
SPIN_LOCK_UNLOCKED
;
#endif
static
int
ipv6_count_addresses
(
struct
inet6_dev
*
idev
);
...
...
@@ -172,7 +174,7 @@ static struct ipv6_devconf ipv6_devconf_dflt =
const
struct
in6_addr
in6addr_any
=
IN6ADDR_ANY_INIT
;
const
struct
in6_addr
in6addr_loopback
=
IN6ADDR_LOOPBACK_INIT
;
int
ipv6_addr_type
(
struct
in6_addr
*
addr
)
int
ipv6_addr_type
(
const
struct
in6_addr
*
addr
)
{
int
type
;
u32
st
;
...
...
@@ -426,8 +428,7 @@ static void dev_forward_change(struct inet6_dev *idev)
}
for
(
ifa
=
idev
->
addr_list
;
ifa
;
ifa
=
ifa
->
if_next
)
{
ipv6_addr_prefix
(
&
addr
,
&
ifa
->
addr
,
ifa
->
prefix_len
);
if
(
addr
.
s6_addr32
[
0
]
==
0
&&
addr
.
s6_addr32
[
1
]
==
0
&&
addr
.
s6_addr32
[
2
]
==
0
&&
addr
.
s6_addr32
[
3
]
==
0
)
if
(
ipv6_addr_any
(
&
addr
))
continue
;
if
(
idev
->
cnf
.
forwarding
)
ipv6_dev_ac_inc
(
idev
->
dev
,
&
addr
);
...
...
@@ -486,7 +487,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
/* On success it returns ifp with increased reference count */
static
struct
inet6_ifaddr
*
ipv6_add_addr
(
struct
inet6_dev
*
idev
,
struct
in6_addr
*
addr
,
int
pfxlen
,
ipv6_add_addr
(
struct
inet6_dev
*
idev
,
const
struct
in6_addr
*
addr
,
int
pfxlen
,
int
scope
,
unsigned
flags
)
{
struct
inet6_ifaddr
*
ifa
;
...
...
@@ -1046,7 +1047,6 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev)
struct
net_device
*
dev
;
u8
eui64
[
8
];
u8
digest
[
16
];
struct
crypto_tfm
*
tfm
;
struct
scatterlist
sg
[
2
];
sg
[
0
].
page
=
virt_to_page
(
idev
->
entropy
);
...
...
@@ -1068,18 +1068,16 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev)
get_random_bytes
(
eui64
,
sizeof
(
eui64
));
}
regen:
tfm
=
crypto_alloc_tfm
(
"md5"
,
0
);
if
(
tfm
==
NULL
)
{
if
(
net_ratelimit
())
printk
(
KERN_WARNING
"failed to load transform for md5
\n
"
);
spin_lock
(
&
md5_tfm_lock
);
if
(
unlikely
(
md5_tfm
==
NULL
))
{
spin_unlock
(
&
md5_tfm_lock
);
in6_dev_put
(
idev
);
return
-
1
;
}
crypto_digest_init
(
tfm
);
crypto_digest_update
(
tfm
,
sg
,
2
);
crypto_digest_final
(
tfm
,
digest
);
crypto_free_tfm
(
tfm
);
crypto_digest_init
(
md5_
tfm
);
crypto_digest_update
(
md5_
tfm
,
sg
,
2
);
crypto_digest_final
(
md5_
tfm
,
digest
);
spin_unlock
(
&
md5_tfm_lock
);
memcpy
(
idev
->
rndid
,
&
digest
[
0
],
8
);
idev
->
rndid
[
0
]
&=
~
0x02
;
...
...
@@ -1107,6 +1105,9 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev)
goto
regen
;
}
idev
->
regen_timer
.
expires
=
jiffies
+
idev
->
cnf
.
temp_prefered_lft
*
HZ
-
idev
->
cnf
.
regen_max_retry
*
idev
->
cnf
.
dad_transmits
*
idev
->
nd_parms
->
retrans_time
-
desync_factor
;
if
(
time_before
(
idev
->
regen_timer
.
expires
,
jiffies
))
{
idev
->
regen_timer
.
expires
=
0
;
printk
(
KERN_WARNING
...
...
@@ -1646,7 +1647,6 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
static
void
init_loopback
(
struct
net_device
*
dev
)
{
struct
in6_addr
addr
;
struct
inet6_dev
*
idev
;
struct
inet6_ifaddr
*
ifp
;
...
...
@@ -1654,15 +1654,12 @@ static void init_loopback(struct net_device *dev)
ASSERT_RTNL
();
memset
(
&
addr
,
0
,
sizeof
(
struct
in6_addr
));
addr
.
s6_addr
[
15
]
=
1
;
if
((
idev
=
ipv6_find_idev
(
dev
))
==
NULL
)
{
printk
(
KERN_DEBUG
"init loopback: add_dev failed
\n
"
);
return
;
}
ifp
=
ipv6_add_addr
(
idev
,
&
addr
,
128
,
IFA_HOST
,
IFA_F_PERMANENT
);
ifp
=
ipv6_add_addr
(
idev
,
&
in6addr_loopback
,
128
,
IFA_HOST
,
IFA_F_PERMANENT
);
if
(
ifp
)
{
spin_lock_bh
(
&
ifp
->
lock
);
ifp
->
flags
&=
~
IFA_F_TENTATIVE
;
...
...
@@ -2034,8 +2031,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
struct
in6_addr
addr
;
ipv6_addr_prefix
(
&
addr
,
&
ifp
->
addr
,
ifp
->
prefix_len
);
if
(
addr
.
s6_addr32
[
0
]
||
addr
.
s6_addr32
[
1
]
||
addr
.
s6_addr32
[
2
]
||
addr
.
s6_addr32
[
3
])
if
(
!
ipv6_addr_any
(
&
addr
))
ipv6_dev_ac_inc
(
ifp
->
idev
->
dev
,
&
addr
);
}
}
...
...
@@ -2372,8 +2368,7 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
struct
in6_addr
addr
;
ipv6_addr_prefix
(
&
addr
,
&
ifp
->
addr
,
ifp
->
prefix_len
);
if
(
addr
.
s6_addr32
[
0
]
||
addr
.
s6_addr32
[
1
]
||
addr
.
s6_addr32
[
2
]
||
addr
.
s6_addr32
[
3
])
if
(
!
ipv6_addr_any
(
&
addr
))
ipv6_dev_ac_dec
(
ifp
->
idev
->
dev
,
&
addr
);
}
if
(
!
ipv6_chk_addr
(
&
ifp
->
addr
,
NULL
))
...
...
@@ -2654,7 +2649,16 @@ void __init addrconf_init(void)
{
#ifdef MODULE
struct
net_device
*
dev
;
#endif
#ifdef CONFIG_IPV6_PRIVACY
md5_tfm
=
crypto_alloc_tfm
(
"md5"
,
0
);
if
(
unlikely
(
md5_tfm
==
NULL
))
printk
(
KERN_WARNING
"failed to load transform for md5
\n
"
);
#endif
#ifdef MODULE
/* This takes sense only during module load. */
rtnl_lock
();
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
{
...
...
@@ -2739,6 +2743,13 @@ void addrconf_cleanup(void)
rtnl_unlock
();
#ifdef CONFIG_IPV6_PRIVACY
if
(
likely
(
md5_tfm
!=
NULL
))
{
crypto_free_tfm
(
md5_tfm
);
md5_tfm
=
NULL
;
}
#endif
#ifdef CONFIG_PROC_FS
proc_net_remove
(
"if_inet6"
);
#endif
...
...
net/ipv6/af_inet6.c
View file @
83a0e2be
...
...
@@ -799,6 +799,13 @@ static int __init inet6_init(void)
addrconf_init
();
sit_init
();
/* Init v6 extention headers. */
ipv6_hopopts_init
();
ipv6_rthdr_init
();
ipv6_frag_init
();
ipv6_nodata_init
();
ipv6_destopt_init
();
/* Init v6 transport protocols. */
udpv6_init
();
tcpv6_init
();
...
...
net/ipv6/exthdrs.c
View file @
83a0e2be
...
...
@@ -18,6 +18,9 @@
/* Changes:
* yoshfuji : ensure not to overrun while parsing
* tlv options.
* Mitsuru KANDA @USAGI : Remove ipv6_parse_exthdrs().
* : Register inbound extention header
* : handlers as inet6_protocol{}.
*/
#include <linux/errno.h>
...
...
@@ -43,20 +46,6 @@
#include <asm/uaccess.h>
/*
* Parsing inbound headers.
*
* Parsing function "func" returns offset wrt skb->nh of the place,
* where next nexthdr value is stored or NULL, if parsing
* failed. It should also update skb->h tp point at the next header.
*/
struct
hdrtype_proc
{
int
type
;
int
(
*
func
)
(
struct
sk_buff
**
,
int
offset
);
};
/*
* Parsing tlv encoded headers.
*
...
...
@@ -164,49 +153,77 @@ static struct tlvtype_proc tlvprocdestopt_lst[] = {
{
-
1
,
NULL
}
};
static
int
ipv6_dest
_opt
(
struct
sk_buff
**
skb_ptr
,
int
nhoff
)
static
int
ipv6_dest
opt_rcv
(
struct
sk_buff
**
skbp
)
{
struct
sk_buff
*
skb
=*
skb_ptr
;
struct
sk_buff
*
skb
=
*
skbp
;
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
u8
nexthdr
=
0
;
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
8
)
||
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
((
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
)))
{
kfree_skb
(
skb
);
return
-
1
;
return
0
;
}
nexthdr
=
((
struct
ipv6_destopt_hdr
*
)
skb
->
h
.
raw
)
->
nexthdr
;
opt
->
dst1
=
skb
->
h
.
raw
-
skb
->
nh
.
raw
;
if
(
ip6_parse_tlv
(
tlvprocdestopt_lst
,
skb
))
{
skb
->
h
.
raw
+=
((
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
);
return
opt
->
dst1
;
return
-
nexthdr
;
}
return
0
;
}
return
-
1
;
static
struct
inet6_protocol
destopt_protocol
=
{
.
handler
=
ipv6_destopt_rcv
,
};
void
__init
ipv6_destopt_init
(
void
)
{
if
(
inet6_add_protocol
(
&
destopt_protocol
,
IPPROTO_DSTOPTS
)
<
0
)
printk
(
KERN_ERR
"ipv6_destopt_init: Could not register protocol
\n
"
);
}
/********************************
NONE header. No data in packet.
********************************/
static
int
ipv6_nodata
(
struct
sk_buff
**
skb_ptr
,
int
nhoff
)
static
int
ipv6_nodata
_rcv
(
struct
sk_buff
**
skbp
)
{
kfree_skb
(
*
skb_ptr
);
return
-
1
;
struct
sk_buff
*
skb
=
*
skbp
;
kfree_skb
(
skb
);
return
0
;
}
static
struct
inet6_protocol
nodata_protocol
=
{
.
handler
=
ipv6_nodata_rcv
,
};
void
__init
ipv6_nodata_init
(
void
)
{
if
(
inet6_add_protocol
(
&
nodata_protocol
,
IPPROTO_NONE
)
<
0
)
printk
(
KERN_ERR
"ipv6_nodata_init: Could not register protocol
\n
"
);
}
/********************************
Routing header.
********************************/
static
int
ipv6_r
outing_header
(
struct
sk_buff
**
skb_ptr
,
int
nhoff
)
static
int
ipv6_r
thdr_rcv
(
struct
sk_buff
**
skbp
)
{
struct
sk_buff
*
skb
=
*
skb
_ptr
;
struct
sk_buff
*
skb
=
*
skb
p
;
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
struct
in6_addr
*
addr
;
struct
in6_addr
daddr
;
int
addr_type
;
int
n
,
i
;
u8
nexthdr
=
0
;
struct
ipv6_rt_hdr
*
hdr
;
struct
rt0_hdr
*
rthdr
;
...
...
@@ -215,15 +232,16 @@ static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
((
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
)))
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
kfree_skb
(
skb
);
return
-
1
;
return
0
;
}
hdr
=
(
struct
ipv6_rt_hdr
*
)
skb
->
h
.
raw
;
nexthdr
=
hdr
->
nexthdr
;
if
((
ipv6_addr_type
(
&
skb
->
nh
.
ipv6h
->
daddr
)
&
IPV6_ADDR_MULTICAST
)
||
skb
->
pkt_type
!=
PACKET_HOST
)
{
kfree_skb
(
skb
);
return
-
1
;
return
0
;
}
looped_back:
...
...
@@ -232,24 +250,24 @@ static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
skb
->
h
.
raw
+=
(
hdr
->
hdrlen
+
1
)
<<
3
;
opt
->
dst0
=
opt
->
dst1
;
opt
->
dst1
=
0
;
return
(
&
hdr
->
nexthdr
)
-
skb
->
nh
.
raw
;
return
-
nexthdr
;
}
if
(
hdr
->
type
!=
IPV6_SRCRT_TYPE_0
||
(
hdr
->
hdrlen
&
0x01
))
{
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
hdr
->
type
!=
IPV6_SRCRT_TYPE_0
?
2
:
1
);
return
-
1
;
return
0
;
}
/*
* This is the routing header forwarding algorithm from
* RFC
1883, page 17
.
* RFC
2460, page 16
.
*/
n
=
hdr
->
hdrlen
>>
1
;
if
(
hdr
->
segments_left
>
n
)
{
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
&
hdr
->
segments_left
)
-
skb
->
nh
.
raw
);
return
-
1
;
return
0
;
}
/* We are about to mangle packet header. Be careful!
...
...
@@ -259,8 +277,8 @@ static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
struct
sk_buff
*
skb2
=
skb_copy
(
skb
,
GFP_ATOMIC
);
kfree_skb
(
skb
);
if
(
skb2
==
NULL
)
return
-
1
;
*
skb
_ptr
=
skb
=
skb2
;
return
0
;
*
skb
p
=
skb
=
skb2
;
opt
=
(
struct
inet6_skb_parm
*
)
skb2
->
cb
;
hdr
=
(
struct
ipv6_rt_hdr
*
)
skb2
->
h
.
raw
;
}
...
...
@@ -278,7 +296,7 @@ static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
if
(
addr_type
&
IPV6_ADDR_MULTICAST
)
{
kfree_skb
(
skb
);
return
-
1
;
return
0
;
}
ipv6_addr_copy
(
&
daddr
,
addr
);
...
...
@@ -289,23 +307,34 @@ static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
ip6_route_input
(
skb
);
if
(
skb
->
dst
->
error
)
{
dst_input
(
skb
);
return
-
1
;
return
0
;
}
if
(
skb
->
dst
->
dev
->
flags
&
IFF_LOOPBACK
)
{
if
(
skb
->
nh
.
ipv6h
->
hop_limit
<=
1
)
{
icmpv6_send
(
skb
,
ICMPV6_TIME_EXCEED
,
ICMPV6_EXC_HOPLIMIT
,
0
,
skb
->
dev
);
kfree_skb
(
skb
);
return
-
1
;
return
0
;
}
skb
->
nh
.
ipv6h
->
hop_limit
--
;
goto
looped_back
;
}
dst_input
(
skb
);
return
-
1
;
return
0
;
}
static
struct
inet6_protocol
rthdr_protocol
=
{
.
handler
=
ipv6_rthdr_rcv
,
};
void
__init
ipv6_rthdr_init
(
void
)
{
if
(
inet6_add_protocol
(
&
rthdr_protocol
,
IPPROTO_ROUTING
)
<
0
)
printk
(
KERN_ERR
"ipv6_rthdr_init: Could not register protocol
\n
"
);
};
/*
This function inverts received rthdr.
NOTE: specs allow to make it automatically only if
...
...
@@ -371,97 +400,6 @@ ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
return
opt
;
}
/********************************
AUTH header.
********************************/
/*
rfc1826 said, that if a host does not implement AUTH header
it MAY ignore it. We use this hole 8)
Actually, now we can implement OSPFv6 without kernel IPsec.
Authentication for poors may be done in user space with the same success.
Yes, it means, that we allow application to send/receive
raw authentication header. Apparently, we suppose, that it knows
what it does and calculates authentication data correctly.
Certainly, it is possible only for udp and raw sockets, but not for tcp.
AUTH header has 4byte granular length, which kills all the idea
behind AUTOMATIC 64bit alignment of IPv6. Now we will lose
cpu ticks, checking that sender did not something stupid
and opt->hdrlen is even. Shit! --ANK (980730)
*/
static
int
ipv6_auth_hdr
(
struct
sk_buff
**
skb_ptr
,
int
nhoff
)
{
struct
sk_buff
*
skb
=*
skb_ptr
;
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
int
len
;
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
8
))
goto
fail
;
/*
* RFC2402 2.2 Payload Length
* The 8-bit field specifies the length of AH in 32-bit words
* (4-byte units), minus "2".
* -- Noriaki Takamiya @USAGI Project
*/
len
=
(
skb
->
h
.
raw
[
1
]
+
2
)
<<
2
;
if
(
len
&
7
)
goto
fail
;
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
len
))
goto
fail
;
opt
->
auth
=
skb
->
h
.
raw
-
skb
->
nh
.
raw
;
skb
->
h
.
raw
+=
len
;
return
opt
->
auth
;
fail:
kfree_skb
(
skb
);
return
-
1
;
}
/* This list MUST NOT contain entry for NEXTHDR_HOP.
It is parsed immediately after packet received
and if it occurs somewhere in another place we must
generate error.
*/
static
struct
hdrtype_proc
hdrproc_lst
[]
=
{
{
NEXTHDR_FRAGMENT
,
ipv6_reassembly
},
{
NEXTHDR_ROUTING
,
ipv6_routing_header
},
{
NEXTHDR_DEST
,
ipv6_dest_opt
},
{
NEXTHDR_NONE
,
ipv6_nodata
},
{
NEXTHDR_AUTH
,
ipv6_auth_hdr
},
/*
{NEXTHDR_ESP, ipv6_esp_hdr},
*/
{
-
1
,
NULL
}
};
int
ipv6_parse_exthdrs
(
struct
sk_buff
**
skb_in
,
int
nhoff
)
{
struct
hdrtype_proc
*
hdrt
;
u8
nexthdr
=
(
*
skb_in
)
->
nh
.
raw
[
nhoff
];
restart:
for
(
hdrt
=
hdrproc_lst
;
hdrt
->
type
>=
0
;
hdrt
++
)
{
if
(
hdrt
->
type
==
nexthdr
)
{
if
((
nhoff
=
hdrt
->
func
(
skb_in
,
nhoff
))
>=
0
)
{
nexthdr
=
(
*
skb_in
)
->
nh
.
raw
[
nhoff
];
goto
restart
;
}
return
-
1
;
}
}
return
nhoff
;
}
/**********************************
Hop-by-hop options.
**********************************/
...
...
@@ -532,6 +470,34 @@ int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
return
-
1
;
}
/* This is fake. We have already parsed hopopts in ipv6_rcv(). -mk */
static
int
ipv6_hopopts_rcv
(
struct
sk_buff
**
skbp
)
{
struct
sk_buff
*
skb
=
*
skbp
;
u8
nexthdr
=
0
;
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
8
)
||
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
((
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
)))
{
kfree_skb
(
skb
);
return
0
;
}
nexthdr
=
((
struct
ipv6_hopopt_hdr
*
)
skb
->
h
.
raw
)
->
nexthdr
;
skb
->
h
.
raw
+=
(
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
;
return
-
nexthdr
;
}
static
struct
inet6_protocol
hopopts_protocol
=
{
.
handler
=
ipv6_hopopts_rcv
,
};
void
__init
ipv6_hopopts_init
(
void
)
{
if
(
inet6_add_protocol
(
&
hopopts_protocol
,
IPPROTO_HOPOPTS
)
<
0
)
printk
(
KERN_ERR
"ipv6_hopopts_init: Could not register protocol
\n
"
);
}
/*
* Creating outbound headers.
*
...
...
net/ipv6/icmp.c
View file @
83a0e2be
...
...
@@ -74,7 +74,7 @@ DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
static
struct
socket
*
__icmpv6_socket
[
NR_CPUS
];
#define icmpv6_socket __icmpv6_socket[smp_processor_id()]
static
int
icmpv6_rcv
(
struct
sk_buff
*
skb
);
static
int
icmpv6_rcv
(
struct
sk_buff
*
*
p
skb
);
static
struct
inet6_protocol
icmpv6_protocol
=
{
.
handler
=
icmpv6_rcv
,
...
...
@@ -459,8 +459,9 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
* Handle icmp messages
*/
static
int
icmpv6_rcv
(
struct
sk_buff
*
skb
)
static
int
icmpv6_rcv
(
struct
sk_buff
*
*
p
skb
)
{
struct
sk_buff
*
skb
=
*
pskb
;
struct
net_device
*
dev
=
skb
->
dev
;
struct
in6_addr
*
saddr
,
*
daddr
;
struct
ipv6hdr
*
orig_hdr
;
...
...
net/ipv6/ip6_input.c
View file @
83a0e2be
...
...
@@ -15,6 +15,10 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
/* Changes
*
* Mitsuru KANDA @USAGI : Remove ipv6_parse_exthdrs().
*/
#include <linux/errno.h>
#include <linux/types.h>
...
...
@@ -126,39 +130,11 @@ static inline int ip6_input_finish(struct sk_buff *skb)
struct
ipv6hdr
*
hdr
=
skb
->
nh
.
ipv6h
;
struct
inet6_protocol
*
ipprot
;
struct
sock
*
raw_sk
;
int
nhoff
;
int
nexthdr
;
int
nexthdr
=
hdr
->
nexthdr
;
u8
hash
;
skb
->
h
.
raw
=
skb
->
nh
.
raw
+
sizeof
(
struct
ipv6hdr
);
/*
* Parse extension headers
*/
nexthdr
=
hdr
->
nexthdr
;
nhoff
=
offsetof
(
struct
ipv6hdr
,
nexthdr
);
/* Skip hop-by-hop options, they are already parsed. */
if
(
nexthdr
==
NEXTHDR_HOP
)
{
nhoff
=
sizeof
(
struct
ipv6hdr
);
nexthdr
=
skb
->
h
.
raw
[
0
];
skb
->
h
.
raw
+=
(
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
;
}
/* This check is sort of optimization.
It would be stupid to detect for optional headers,
which are missing with probability of 200%
*/
if
(
nexthdr
!=
IPPROTO_TCP
&&
nexthdr
!=
IPPROTO_UDP
&&
nexthdr
!=
NEXTHDR_AUTH
&&
nexthdr
!=
NEXTHDR_ESP
)
{
nhoff
=
ipv6_parse_exthdrs
(
&
skb
,
nhoff
);
if
(
nhoff
<
0
)
return
0
;
nexthdr
=
skb
->
nh
.
raw
[
nhoff
];
hdr
=
skb
->
nh
.
ipv6h
;
}
if
(
!
pskb_pull
(
skb
,
skb
->
h
.
raw
-
skb
->
data
))
goto
discard
;
...
...
@@ -173,7 +149,7 @@ static inline int ip6_input_finish(struct sk_buff *skb)
hash
=
nexthdr
&
(
MAX_INET_PROTOS
-
1
);
if
((
ipprot
=
inet6_protos
[
hash
])
!=
NULL
)
{
int
ret
=
ipprot
->
handler
(
skb
);
int
ret
=
ipprot
->
handler
(
&
skb
);
if
(
ret
<
0
)
{
nexthdr
=
-
ret
;
goto
resubmit
;
...
...
@@ -182,7 +158,8 @@ static inline int ip6_input_finish(struct sk_buff *skb)
}
else
{
if
(
!
raw_sk
)
{
IP6_INC_STATS_BH
(
Ip6InUnknownProtos
);
icmpv6_param_prob
(
skb
,
ICMPV6_UNK_NEXTHDR
,
nhoff
);
icmpv6_param_prob
(
skb
,
ICMPV6_UNK_NEXTHDR
,
offsetof
(
struct
ipv6hdr
,
nexthdr
));
}
else
{
IP6_INC_STATS_BH
(
Ip6InDelivers
);
kfree_skb
(
skb
);
...
...
net/ipv6/reassembly.c
View file @
83a0e2be
...
...
@@ -23,6 +23,7 @@
* Horst von Brand Add missing #include <linux/string.h>
* Alexey Kuznetsov SMP races, threading, cleanup.
* Patrick McHardy LRU queue of frag heads for evictor.
* Mitsuru KANDA @USAGI Register inet6_protocol{}.
*/
#include <linux/config.h>
#include <linux/errno.h>
...
...
@@ -525,6 +526,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
int
remove_fraghdr
=
0
;
int
payload_len
;
int
nhoff
;
u8
nexthdr
=
0
;
fq_kill
(
fq
);
...
...
@@ -535,6 +537,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
payload_len
=
(
head
->
data
-
head
->
nh
.
raw
)
-
sizeof
(
struct
ipv6hdr
)
+
fq
->
len
;
nhoff
=
head
->
h
.
raw
-
head
->
nh
.
raw
;
nexthdr
=
((
struct
frag_hdr
*
)
head
->
h
.
raw
)
->
nexthdr
;
if
(
payload_len
>
65535
)
{
payload_len
-=
8
;
if
(
payload_len
>
65535
)
...
...
@@ -609,9 +613,12 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
if
(
head
->
ip_summed
==
CHECKSUM_HW
)
head
->
csum
=
csum_partial
(
head
->
nh
.
raw
,
head
->
h
.
raw
-
head
->
nh
.
raw
,
head
->
csum
);
if
(
!
pskb_pull
(
head
,
head
->
h
.
raw
-
head
->
data
))
goto
out_fail
;
IP6_INC_STATS_BH
(
Ip6ReasmOKs
);
fq
->
fragments
=
NULL
;
return
n
hoff
;
return
n
exthdr
;
out_oversize:
if
(
net_ratelimit
())
...
...
@@ -622,16 +629,18 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
printk
(
KERN_DEBUG
"ip6_frag_reasm: no memory for reassembly
\n
"
);
out_fail:
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
return
-
1
;
return
0
;
}
int
ipv6_reassembly
(
struct
sk_buff
**
skbp
,
int
nhoff
)
static
int
ipv6_frag_rcv
(
struct
sk_buff
**
skbp
)
{
struct
sk_buff
*
skb
=
*
skbp
;
struct
net_device
*
dev
=
skb
->
dev
;
struct
frag_hdr
*
fhdr
;
struct
frag_queue
*
fq
;
struct
ipv6hdr
*
hdr
;
int
nhoff
=
skb
->
h
.
raw
-
skb
->
nh
.
raw
;
u8
nexthdr
=
0
;
hdr
=
skb
->
nh
.
ipv6h
;
...
...
@@ -640,15 +649,16 @@ int ipv6_reassembly(struct sk_buff **skbp, int nhoff)
/* Jumbo payload inhibits frag. header */
if
(
hdr
->
payload_len
==
0
)
{
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
);
return
-
1
;
goto
discard
;
}
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
sizeof
(
struct
frag_hdr
)))
{
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
);
return
-
1
;
goto
discard
;
}
hdr
=
skb
->
nh
.
ipv6h
;
fhdr
=
(
struct
frag_hdr
*
)
skb
->
h
.
raw
;
nexthdr
=
fhdr
->
nexthdr
;
if
(
!
(
fhdr
->
frag_off
&
htons
(
0xFFF9
)))
{
/* It is not a fragmented frame */
...
...
@@ -674,10 +684,22 @@ int ipv6_reassembly(struct sk_buff **skbp, int nhoff)
spin_unlock
(
&
fq
->
lock
);
fq_put
(
fq
);
return
ret
;
return
-
ret
;
}
discard:
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
kfree_skb
(
skb
);
return
-
1
;
return
0
;
}
static
struct
inet6_protocol
frag_protocol
=
{
.
handler
=
ipv6_frag_rcv
,
};
void
__init
ipv6_frag_init
(
void
)
{
if
(
inet6_add_protocol
(
&
frag_protocol
,
IPPROTO_FRAGMENT
)
<
0
)
printk
(
KERN_ERR
"ipv6_frag_init: Could not register protocol
\n
"
);
}
net/ipv6/tcp_ipv6.c
View file @
83a0e2be
...
...
@@ -1591,8 +1591,9 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
return
0
;
}
static
int
tcp_v6_rcv
(
struct
sk_buff
*
skb
)
static
int
tcp_v6_rcv
(
struct
sk_buff
*
*
p
skb
)
{
struct
sk_buff
*
skb
=
*
pskb
;
struct
tcphdr
*
th
;
struct
sock
*
sk
;
int
ret
;
...
...
net/ipv6/udp.c
View file @
83a0e2be
...
...
@@ -641,8 +641,9 @@ static void udpv6_mcast_deliver(struct udphdr *uh,
read_unlock
(
&
udp_hash_lock
);
}
static
int
udpv6_rcv
(
struct
sk_buff
*
skb
)
static
int
udpv6_rcv
(
struct
sk_buff
*
*
p
skb
)
{
struct
sk_buff
*
skb
=
*
pskb
;
struct
sock
*
sk
;
struct
udphdr
*
uh
;
struct
net_device
*
dev
=
skb
->
dev
;
...
...
net/ipv6/xfrm6_input.c
View file @
83a0e2be
...
...
@@ -123,8 +123,9 @@ int xfrm6_clear_mutable_options(struct sk_buff *skb, u16 *nh_offset, int dir)
return
nexthdr
;
}
int
xfrm6_rcv
(
struct
sk_buff
*
skb
)
int
xfrm6_rcv
(
struct
sk_buff
*
*
p
skb
)
{
struct
sk_buff
*
skb
=
*
pskb
;
int
err
;
u32
spi
,
seq
;
struct
xfrm_state
*
xfrm_vec
[
XFRM_MAX_DEPTH
];
...
...
@@ -137,12 +138,8 @@ int xfrm6_rcv(struct sk_buff *skb)
u16
nh_offset
=
0
;
u8
nexthdr
=
0
;
if
(
hdr
->
nexthdr
==
IPPROTO_AH
||
hdr
->
nexthdr
==
IPPROTO_ESP
)
{
nh_offset
=
((
unsigned
char
*
)
&
skb
->
nh
.
ipv6h
->
nexthdr
)
-
skb
->
nh
.
raw
;
hdr_len
=
sizeof
(
struct
ipv6hdr
);
}
else
{
hdr_len
=
skb
->
h
.
raw
-
skb
->
nh
.
raw
;
}
nh_offset
=
((
unsigned
char
*
)
&
skb
->
nh
.
ipv6h
->
nexthdr
)
-
skb
->
nh
.
raw
;
hdr_len
=
sizeof
(
struct
ipv6hdr
);
tmp_hdr
=
kmalloc
(
hdr_len
,
GFP_ATOMIC
);
if
(
!
tmp_hdr
)
...
...
@@ -189,20 +186,6 @@ int xfrm6_rcv(struct sk_buff *skb)
xfrm_vec
[
xfrm_nr
++
]
=
x
;
iph
=
skb
->
nh
.
ipv6h
;
/* ??? */
if
(
nexthdr
==
NEXTHDR_DEST
)
{
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
8
)
||
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
((
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
)))
{
err
=
-
EINVAL
;
goto
drop
;
}
nexthdr
=
skb
->
h
.
raw
[
0
];
nh_offset
=
skb
->
h
.
raw
-
skb
->
nh
.
raw
;
skb_pull
(
skb
,
(
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
);
skb
->
h
.
raw
=
skb
->
data
;
}
if
(
x
->
props
.
mode
)
{
/* XXX */
if
(
iph
->
nexthdr
!=
IPPROTO_IPV6
)
goto
drop
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment