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
12173d80
Commit
12173d80
authored
Dec 31, 2003
by
Hideaki Yoshifuji
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV6]: Kill obsolete functions (ip6_frag_xmit() and ip6_build_xmit()).
parent
f73e9f0f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
0 additions
and
423 deletions
+0
-423
include/net/ipv6.h
include/net/ipv6.h
+0
-7
net/ipv6/ip6_output.c
net/ipv6/ip6_output.c
+0
-416
No files found.
include/net/ipv6.h
View file @
12173d80
...
...
@@ -329,13 +329,6 @@ extern int ip6_nd_hdr(struct sock *sk,
struct
in6_addr
*
daddr
,
int
proto
,
int
len
);
extern
int
ip6_build_xmit
(
struct
sock
*
sk
,
inet_getfrag_t
getfrag
,
const
void
*
data
,
struct
flowi
*
fl
,
unsigned
length
,
struct
ipv6_txoptions
*
opt
,
int
hlimit
,
int
flags
);
extern
int
ip6_find_1stfragopt
(
struct
sk_buff
*
skb
,
u8
**
nexthdr
);
extern
int
ip6_append_data
(
struct
sock
*
sk
,
...
...
net/ipv6/ip6_output.c
View file @
12173d80
...
...
@@ -304,422 +304,6 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
return
0
;
}
static
struct
ipv6hdr
*
ip6_bld_1
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
struct
flowi
*
fl
,
int
hlimit
,
unsigned
pktlength
)
{
struct
ipv6hdr
*
hdr
;
skb
->
nh
.
raw
=
skb_put
(
skb
,
sizeof
(
struct
ipv6hdr
));
hdr
=
skb
->
nh
.
ipv6h
;
*
(
u32
*
)
hdr
=
fl
->
fl6_flowlabel
|
htonl
(
0x60000000
);
hdr
->
payload_len
=
htons
(
pktlength
-
sizeof
(
struct
ipv6hdr
));
hdr
->
hop_limit
=
hlimit
;
hdr
->
nexthdr
=
fl
->
proto
;
ipv6_addr_copy
(
&
hdr
->
saddr
,
&
fl
->
fl6_src
);
ipv6_addr_copy
(
&
hdr
->
daddr
,
&
fl
->
fl6_dst
);
return
hdr
;
}
static
__inline__
u8
*
ipv6_build_fraghdr
(
struct
sk_buff
*
skb
,
u8
*
prev_hdr
,
unsigned
offset
)
{
struct
frag_hdr
*
fhdr
;
fhdr
=
(
struct
frag_hdr
*
)
skb_put
(
skb
,
sizeof
(
struct
frag_hdr
));
fhdr
->
nexthdr
=
*
prev_hdr
;
*
prev_hdr
=
NEXTHDR_FRAGMENT
;
prev_hdr
=
&
fhdr
->
nexthdr
;
fhdr
->
reserved
=
0
;
fhdr
->
frag_off
=
htons
(
offset
);
ipv6_select_ident
(
skb
,
fhdr
);
return
&
fhdr
->
nexthdr
;
}
static
int
ip6_frag_xmit
(
struct
sock
*
sk
,
inet_getfrag_t
getfrag
,
const
void
*
data
,
struct
dst_entry
*
dst
,
struct
flowi
*
fl
,
struct
ipv6_txoptions
*
opt
,
struct
in6_addr
*
final_dst
,
int
hlimit
,
int
flags
,
unsigned
length
,
int
mtu
)
{
struct
ipv6hdr
*
hdr
;
struct
sk_buff
*
last_skb
;
u8
*
prev_hdr
;
int
unfrag_len
;
int
frag_len
;
int
last_len
;
int
nfrags
;
int
fhdr_dist
;
int
frag_off
;
int
data_off
;
int
err
;
/*
* Fragmentation
*
* Extension header order:
* Hop-by-hop -> Dest0 -> Routing -> Fragment -> Auth -> Dest1 -> rest (...)
*
* We must build the non-fragmented part that
* will be in every packet... this also means
* that other extension headers (Dest, Auth, etc)
* must be considered in the data to be fragmented
*/
unfrag_len
=
sizeof
(
struct
ipv6hdr
)
+
sizeof
(
struct
frag_hdr
);
last_len
=
length
;
if
(
opt
)
{
unfrag_len
+=
opt
->
opt_nflen
;
last_len
+=
opt
->
opt_flen
;
}
/*
* Length of fragmented part on every packet but
* the last must be an:
* "integer multiple of 8 octets".
*/
frag_len
=
(
mtu
-
unfrag_len
)
&
~
0x7
;
/* Unfragmentable part exceeds mtu. */
if
(
frag_len
<=
0
)
{
ipv6_local_error
(
sk
,
EMSGSIZE
,
fl
,
mtu
);
return
-
EMSGSIZE
;
}
nfrags
=
last_len
/
frag_len
;
/*
* We must send from end to start because of
* UDP/ICMP checksums. We do a funny trick:
* fill the last skb first with the fixed
* header (and its data) and then use it
* to create the following segments and send it
* in the end. If the peer is checking the M_flag
* to trigger the reassembly code then this
* might be a good idea.
*/
frag_off
=
nfrags
*
frag_len
;
last_len
-=
frag_off
;
if
(
last_len
==
0
)
{
last_len
=
frag_len
;
frag_off
-=
frag_len
;
nfrags
--
;
}
data_off
=
frag_off
;
/* And it is implementation problem: for now we assume, that
all the exthdrs will fit to the first fragment.
*/
if
(
opt
)
{
if
(
frag_len
<
opt
->
opt_flen
)
{
ipv6_local_error
(
sk
,
EMSGSIZE
,
fl
,
mtu
);
return
-
EMSGSIZE
;
}
data_off
=
frag_off
-
opt
->
opt_flen
;
}
if
(
flags
&
MSG_PROBE
)
return
0
;
last_skb
=
sock_alloc_send_skb
(
sk
,
unfrag_len
+
frag_len
+
dst
->
dev
->
hard_header_len
+
15
,
flags
&
MSG_DONTWAIT
,
&
err
);
if
(
last_skb
==
NULL
)
return
err
;
last_skb
->
dst
=
dst_clone
(
dst
);
skb_reserve
(
last_skb
,
(
dst
->
dev
->
hard_header_len
+
15
)
&
~
15
);
hdr
=
ip6_bld_1
(
sk
,
last_skb
,
fl
,
hlimit
,
frag_len
+
unfrag_len
);
prev_hdr
=
&
hdr
->
nexthdr
;
if
(
opt
&&
opt
->
opt_nflen
)
prev_hdr
=
ipv6_build_nfrag_opts
(
last_skb
,
prev_hdr
,
opt
,
final_dst
,
0
);
prev_hdr
=
ipv6_build_fraghdr
(
last_skb
,
prev_hdr
,
frag_off
);
fhdr_dist
=
prev_hdr
-
last_skb
->
data
;
err
=
getfrag
(
data
,
&
hdr
->
saddr
,
last_skb
->
tail
,
data_off
,
last_len
);
if
(
!
err
)
{
while
(
nfrags
--
)
{
struct
sk_buff
*
skb
;
struct
frag_hdr
*
fhdr2
;
skb
=
skb_copy
(
last_skb
,
sk
->
sk_allocation
);
if
(
skb
==
NULL
)
{
IP6_INC_STATS
(
Ip6FragFails
);
kfree_skb
(
last_skb
);
return
-
ENOMEM
;
}
frag_off
-=
frag_len
;
data_off
-=
frag_len
;
fhdr2
=
(
struct
frag_hdr
*
)
(
skb
->
data
+
fhdr_dist
);
/* more flag on */
fhdr2
->
frag_off
=
htons
(
frag_off
|
1
);
/* Write fragmentable exthdrs to the first chunk */
if
(
nfrags
==
0
&&
opt
&&
opt
->
opt_flen
)
{
ipv6_build_frag_opts
(
skb
,
&
fhdr2
->
nexthdr
,
opt
);
frag_len
-=
opt
->
opt_flen
;
data_off
=
0
;
}
err
=
getfrag
(
data
,
&
hdr
->
saddr
,
skb_put
(
skb
,
frag_len
),
data_off
,
frag_len
);
if
(
err
)
{
kfree_skb
(
skb
);
break
;
}
IP6_INC_STATS
(
Ip6FragCreates
);
IP6_INC_STATS
(
Ip6OutRequests
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
ip6_maybe_reroute
);
if
(
err
)
{
kfree_skb
(
last_skb
);
return
err
;
}
}
}
if
(
err
)
{
IP6_INC_STATS
(
Ip6FragFails
);
kfree_skb
(
last_skb
);
return
-
EFAULT
;
}
hdr
->
payload_len
=
htons
(
unfrag_len
+
last_len
-
sizeof
(
struct
ipv6hdr
));
/*
* update last_skb to reflect the getfrag we did
* on start.
*/
skb_put
(
last_skb
,
last_len
);
IP6_INC_STATS
(
Ip6FragCreates
);
IP6_INC_STATS
(
Ip6FragOKs
);
IP6_INC_STATS
(
Ip6OutRequests
);
return
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
last_skb
,
NULL
,
dst
->
dev
,
ip6_maybe_reroute
);
}
int
ip6_build_xmit
(
struct
sock
*
sk
,
inet_getfrag_t
getfrag
,
const
void
*
data
,
struct
flowi
*
fl
,
unsigned
length
,
struct
ipv6_txoptions
*
opt
,
int
hlimit
,
int
flags
)
{
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
in6_addr
final_dst_buf
,
*
final_dst
=
NULL
;
struct
dst_entry
*
dst
;
int
err
=
0
;
unsigned
int
pktlength
,
jumbolen
,
mtu
;
if
(
opt
&&
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
opt
->
srcrt
;
ipv6_addr_copy
(
&
final_dst_buf
,
&
fl
->
fl6_dst
);
final_dst
=
&
final_dst_buf
;
ipv6_addr_copy
(
&
fl
->
fl6_dst
,
rt0
->
addr
);
}
if
(
!
fl
->
oif
&&
ipv6_addr_is_multicast
(
&
fl
->
fl6_dst
))
fl
->
oif
=
np
->
mcast_oif
;
dst
=
__sk_dst_check
(
sk
,
np
->
dst_cookie
);
if
(
dst
)
{
struct
rt6_info
*
rt
=
(
struct
rt6_info
*
)
dst
;
/* Yes, checking route validity in not connected
case is not very simple. Take into account,
that we do not support routing by source, TOS,
and MSG_DONTROUTE --ANK (980726)
1. If route was host route, check that
cached destination is current.
If it is network route, we still may
check its validity using saved pointer
to the last used address: daddr_cache.
We do not want to save whole address now,
(because main consumer of this service
is tcp, which has not this problem),
so that the last trick works only on connected
sockets.
2. oif also should be the same.
*/
if
(((
rt
->
rt6i_dst
.
plen
!=
128
||
ipv6_addr_cmp
(
&
fl
->
fl6_dst
,
&
rt
->
rt6i_dst
.
addr
))
&&
(
np
->
daddr_cache
==
NULL
||
ipv6_addr_cmp
(
&
fl
->
fl6_dst
,
np
->
daddr_cache
)))
||
(
fl
->
oif
&&
fl
->
oif
!=
dst
->
dev
->
ifindex
))
{
dst
=
NULL
;
}
else
dst_hold
(
dst
);
}
if
(
dst
==
NULL
)
dst
=
ip6_route_output
(
sk
,
fl
);
if
(
dst
->
error
)
{
IP6_INC_STATS
(
Ip6OutNoRoutes
);
dst_release
(
dst
);
return
-
ENETUNREACH
;
}
if
(
ipv6_addr_any
(
&
fl
->
fl6_src
))
{
err
=
ipv6_get_saddr
(
dst
,
&
fl
->
fl6_dst
,
&
fl
->
fl6_src
);
if
(
err
)
{
#if IP6_DEBUG >= 2
printk
(
KERN_DEBUG
"ip6_build_xmit: "
"no available source address
\n
"
);
#endif
goto
out
;
}
}
pktlength
=
length
;
if
(
dst
)
{
if
((
err
=
xfrm_lookup
(
&
dst
,
fl
,
sk
,
0
))
<
0
)
{
dst_release
(
dst
);
return
-
ENETUNREACH
;
}
}
if
(
hlimit
<
0
)
{
if
(
ipv6_addr_is_multicast
(
&
fl
->
fl6_dst
))
hlimit
=
np
->
mcast_hops
;
else
hlimit
=
np
->
hop_limit
;
if
(
hlimit
<
0
)
hlimit
=
dst_metric
(
dst
,
RTAX_HOPLIMIT
);
}
jumbolen
=
0
;
if
(
!
inet
->
hdrincl
)
{
pktlength
+=
sizeof
(
struct
ipv6hdr
);
if
(
opt
)
pktlength
+=
opt
->
opt_flen
+
opt
->
opt_nflen
;
if
(
pktlength
>
sizeof
(
struct
ipv6hdr
)
+
IPV6_MAXPLEN
)
{
/* Jumbo datagram.
It is assumed, that in the case of hdrincl
jumbo option is supplied by user.
*/
pktlength
+=
8
;
jumbolen
=
pktlength
-
sizeof
(
struct
ipv6hdr
);
}
}
mtu
=
dst_pmtu
(
dst
);
if
(
np
->
frag_size
<
mtu
)
{
if
(
np
->
frag_size
)
mtu
=
np
->
frag_size
;
else
if
(
np
->
pmtudisc
==
IPV6_PMTUDISC_DONT
)
mtu
=
IPV6_MIN_MTU
;
}
/* Critical arithmetic overflow check.
FIXME: may gcc optimize it out? --ANK (980726)
*/
if
(
pktlength
<
length
)
{
ipv6_local_error
(
sk
,
EMSGSIZE
,
fl
,
mtu
);
err
=
-
EMSGSIZE
;
goto
out
;
}
if
(
flags
&
MSG_CONFIRM
)
dst_confirm
(
dst
);
if
(
pktlength
<=
mtu
)
{
struct
sk_buff
*
skb
;
struct
ipv6hdr
*
hdr
;
struct
net_device
*
dev
=
dst
->
dev
;
err
=
0
;
if
(
flags
&
MSG_PROBE
)
goto
out
;
/* alloc skb with mtu as we do in the IPv4 stack for IPsec */
skb
=
sock_alloc_send_skb
(
sk
,
mtu
+
LL_RESERVED_SPACE
(
dev
),
flags
&
MSG_DONTWAIT
,
&
err
);
if
(
skb
==
NULL
)
{
IP6_INC_STATS
(
Ip6OutDiscards
);
goto
out
;
}
skb
->
dst
=
dst_clone
(
dst
);
skb_reserve
(
skb
,
(
dev
->
hard_header_len
+
15
)
&
~
15
);
hdr
=
(
struct
ipv6hdr
*
)
skb
->
tail
;
skb
->
nh
.
ipv6h
=
hdr
;
if
(
!
inet
->
hdrincl
)
{
ip6_bld_1
(
sk
,
skb
,
fl
,
hlimit
,
jumbolen
?
sizeof
(
struct
ipv6hdr
)
:
pktlength
);
if
(
opt
||
jumbolen
)
{
u8
*
prev_hdr
=
&
hdr
->
nexthdr
;
prev_hdr
=
ipv6_build_nfrag_opts
(
skb
,
prev_hdr
,
opt
,
final_dst
,
jumbolen
);
if
(
opt
&&
opt
->
opt_flen
)
ipv6_build_frag_opts
(
skb
,
prev_hdr
,
opt
);
}
}
skb_put
(
skb
,
length
);
err
=
getfrag
(
data
,
&
hdr
->
saddr
,
((
char
*
)
hdr
)
+
(
pktlength
-
length
),
0
,
length
);
if
(
!
opt
||
!
opt
->
dst1opt
)
skb
->
h
.
raw
=
((
char
*
)
hdr
)
+
(
pktlength
-
length
);
if
(
!
err
)
{
IP6_INC_STATS
(
Ip6OutRequests
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
ip6_maybe_reroute
);
}
else
{
err
=
-
EFAULT
;
kfree_skb
(
skb
);
}
}
else
{
if
(
inet
->
hdrincl
||
jumbolen
||
np
->
pmtudisc
==
IPV6_PMTUDISC_DO
)
{
ipv6_local_error
(
sk
,
EMSGSIZE
,
fl
,
mtu
);
err
=
-
EMSGSIZE
;
goto
out
;
}
err
=
ip6_frag_xmit
(
sk
,
getfrag
,
data
,
dst
,
fl
,
opt
,
final_dst
,
hlimit
,
flags
,
length
,
mtu
);
}
/*
* cleanup
*/
out:
ip6_dst_store
(
sk
,
dst
,
!
ipv6_addr_cmp
(
&
fl
->
fl6_dst
,
&
np
->
daddr
)
?
&
np
->
daddr
:
NULL
);
if
(
err
>
0
)
err
=
np
->
recverr
?
net_xmit_errno
(
err
)
:
0
;
return
err
;
}
int
ip6_call_ra_chain
(
struct
sk_buff
*
skb
,
int
sel
)
{
struct
ip6_ra_chain
*
ra
;
...
...
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