Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
cf8cd3d1
Commit
cf8cd3d1
authored
May 26, 2004
by
David S. Miller
Committed by
Dmitry Torokhov
May 26, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cset exclude: mashirle@us.ibm.com|ChangeSet|20040526204412|10895
parent
4d9d9fa9
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
44 additions
and
505 deletions
+44
-505
include/linux/rtnetlink.h
include/linux/rtnetlink.h
+0
-20
include/net/if_inet6.h
include/net/if_inet6.h
+0
-1
include/net/ipv6.h
include/net/ipv6.h
+0
-38
include/net/snmp.h
include/net/snmp.h
+0
-39
net/ipv6/addrconf.c
net/ipv6/addrconf.c
+0
-96
net/ipv6/af_inet6.c
net/ipv6/af_inet6.c
+0
-6
net/ipv6/exthdrs.c
net/ipv6/exthdrs.c
+1
-27
net/ipv6/icmp.c
net/ipv6/icmp.c
+0
-8
net/ipv6/ip6_input.c
net/ipv6/ip6_input.c
+4
-35
net/ipv6/ip6_output.c
net/ipv6/ip6_output.c
+15
-111
net/ipv6/ipv6_sockglue.c
net/ipv6/ipv6_sockglue.c
+0
-1
net/ipv6/mcast.c
net/ipv6/mcast.c
+7
-22
net/ipv6/ndisc.c
net/ipv6/ndisc.c
+1
-5
net/ipv6/proc.c
net/ipv6/proc.c
+1
-13
net/ipv6/raw.c
net/ipv6/raw.c
+6
-19
net/ipv6/reassembly.c
net/ipv6/reassembly.c
+3
-36
net/ipv6/route.c
net/ipv6/route.c
+6
-28
No files found.
include/linux/rtnetlink.h
View file @
cf8cd3d1
...
@@ -44,9 +44,6 @@
...
@@ -44,9 +44,6 @@
#define RTM_DELTFILTER (RTM_BASE+29)
#define RTM_DELTFILTER (RTM_BASE+29)
#define RTM_GETTFILTER (RTM_BASE+30)
#define RTM_GETTFILTER (RTM_BASE+30)
#define RTM_NEWIPSTATS (RTM_BASE+32)
#define RTM_GETIPSTATS (RTM_BASE+34)
#define RTM_NEWPREFIX (RTM_BASE+36)
#define RTM_NEWPREFIX (RTM_BASE+36)
#define RTM_GETPREFIX (RTM_BASE+38)
#define RTM_GETPREFIX (RTM_BASE+38)
...
@@ -640,23 +637,6 @@ enum
...
@@ -640,23 +637,6 @@ enum
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
/********************************************************************
* IP mibs information
****/
struct
ipstatsmsg
{
int
ipstats_family
;
int
ipstats_ifindex
;
};
enum
{
IPSTATS_IFNAME
,
IPSTATS_COUNTERS
,
};
#define IPSTATS_MAX IPSTATS_COUNTERS
/* SUMMARY: maximal rtattr understood by kernel */
/* SUMMARY: maximal rtattr understood by kernel */
...
...
include/net/if_inet6.h
View file @
cf8cd3d1
...
@@ -149,7 +149,6 @@ struct ifacaddr6
...
@@ -149,7 +149,6 @@ struct ifacaddr6
struct
ipv6_devstat
{
struct
ipv6_devstat
{
struct
proc_dir_entry
*
proc_dir_entry
;
struct
proc_dir_entry
*
proc_dir_entry
;
DEFINE_SNMP_STAT
(
struct
icmpv6_mib
,
icmpv6
);
DEFINE_SNMP_STAT
(
struct
icmpv6_mib
,
icmpv6
);
DEFINE_SNMP_STAT
(
struct
ip_stats
,
ipv6
);
};
};
struct
inet6_dev
struct
inet6_dev
...
...
include/net/ipv6.h
View file @
cf8cd3d1
...
@@ -116,44 +116,6 @@ DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
...
@@ -116,44 +116,6 @@ DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
#define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field)
#define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field)
#define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field)
#define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field)
DECLARE_SNMP_STAT
(
struct
icmpv6_mib
,
icmpv6_statistics
);
DECLARE_SNMP_STAT
(
struct
icmpv6_mib
,
icmpv6_statistics
);
/* new IPv6 MIB */
DECLARE_SNMP_STAT
(
struct
ip_stats
,
ipv6_stats
);
#define IPV6_INC_STATS(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(_idev->stats.ipv6, field); \
SNMP_INC_STATS(ipv6_stats, field); \
})
#define IPV6_INC_STATS_BH(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(_idev->stats.ipv6, field); \
SNMP_INC_STATS_BH(ipv6_stats, field); \
})
#define IPV6_INC_STATS_USER(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(_idev->stats.ipv6, field); \
SNMP_INC_STATS_USER(ipv6_stats, field); \
})
#define IPV6_ADD_STATS_BH(idev, field, addend) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_ADD_STATS_BH(_idev->stats.ipv6, field, addend); \
SNMP_ADD_STATS_BH(ipv6_stats, field, addend); \
})
#define IPV6_ADD_STATS_USER(idev, field, addend) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_ADD_STATS_USER(_idev->stats.ipv6, field, addend); \
SNMP_ADD_STATS_USER(ipv6_stats, field, addend); \
})
#define IPV6_ADD_STATS(idev, field, addend) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_ADD_STATS(_idev->stats.ipv6, field, addend); \
SNMP_ADD_STATS(ipv6_stats, field, addend); \
})
#define ICMP6_INC_STATS(idev, field) ({ \
#define ICMP6_INC_STATS(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
if (likely(_idev != NULL)) \
...
...
include/net/snmp.h
View file @
cf8cd3d1
...
@@ -98,43 +98,6 @@ struct ipv6_mib
...
@@ -98,43 +98,6 @@ struct ipv6_mib
unsigned
long
Ip6OutMcastPkts
;
unsigned
long
Ip6OutMcastPkts
;
unsigned
long
__pad
[
0
];
unsigned
long
__pad
[
0
];
};
};
/*
* New IP MIBs from draft-ietf-ipv6-rfc2011-update-05.txt
*/
struct
ip_stats
{
unsigned
long
ipStatsInReceives
;
unsigned
long
ipStatsInOctets
;
unsigned
long
ipStatsInHdrErrors
;
unsigned
long
ipStatsInNoRoutes
;
unsigned
long
ipStatsInAddrErrors
;
unsigned
long
ipStatsInUnknownProtos
;
unsigned
long
ipStatsInTruncatedPkts
;
unsigned
long
ipStatsInForwDatagrams
;
unsigned
long
ipStatsReasmReqds
;
unsigned
long
ipStatsReasmOKs
;
unsigned
long
ipStatsReasmFails
;
unsigned
long
ipStatsInDiscards
;
unsigned
long
ipStatsInDelivers
;
unsigned
long
ipStatsOutRequests
;
unsigned
long
ipStatsOutNoRoutes
;
unsigned
long
ipStatsOutForwDatagrams
;
unsigned
long
ipStatsOutDiscards
;
unsigned
long
ipStatsOutFragReqds
;
unsigned
long
ipStatsOutFragOKs
;
unsigned
long
ipStatsOutFragFails
;
unsigned
long
ipStatsOutFragCreates
;
unsigned
long
ipStatsOutTransmits
;
unsigned
long
ipStatsOutOctets
;
unsigned
long
ipStatsInMcastPkts
;
unsigned
long
ipStatsInMcastOctets
;
unsigned
long
ipStatsOutMcastPkts
;
unsigned
long
ipStatsOutMcastOctets
;
unsigned
long
ipStatsInBcastPkts
;
unsigned
long
ipStatsOutBcastPkts
;
unsigned
long
__pad
[
0
];
};
/*
/*
* RFC 1213: MIB-II ICMP Group
* RFC 1213: MIB-II ICMP Group
...
@@ -372,8 +335,6 @@ struct linux_mib
...
@@ -372,8 +335,6 @@ struct linux_mib
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field++)
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field++)
#define SNMP_DEC_STATS(mib, field) \
#define SNMP_DEC_STATS(mib, field) \
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field--)
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field--)
#define SNMP_ADD_STATS(mib, field, addend) \
(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field += addend)
#define SNMP_ADD_STATS_BH(mib, field, addend) \
#define SNMP_ADD_STATS_BH(mib, field, addend) \
(per_cpu_ptr(mib[0], smp_processor_id())->field += addend)
(per_cpu_ptr(mib[0], smp_processor_id())->field += addend)
#define SNMP_ADD_STATS_USER(mib, field, addend) \
#define SNMP_ADD_STATS_USER(mib, field, addend) \
...
...
net/ipv6/addrconf.c
View file @
cf8cd3d1
...
@@ -2963,101 +2963,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
...
@@ -2963,101 +2963,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
netlink_broadcast
(
rtnl
,
skb
,
0
,
RTMGRP_IPV6_PREFIX
,
GFP_ATOMIC
);
netlink_broadcast
(
rtnl
,
skb
,
0
,
RTMGRP_IPV6_PREFIX
,
GFP_ATOMIC
);
}
}
static
unsigned
long
fold_field
(
void
*
mib
[],
int
offt
)
{
unsigned
long
res
=
0
;
int
i
;
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
!
cpu_possible
(
i
))
continue
;
res
+=
*
((
unsigned
long
*
)
(((
void
*
)
per_cpu_ptr
(
mib
[
0
],
i
))
+
offt
));
res
+=
*
((
unsigned
long
*
)
(((
void
*
)
per_cpu_ptr
(
mib
[
1
],
i
))
+
offt
));
}
return
res
;
}
static
int
inet6_fill_ipstats
(
struct
sk_buff
*
skb
,
struct
inet6_dev
*
idev
,
u32
pid
,
u32
seq
,
int
event
)
{
struct
ipstatsmsg
*
r
;
struct
nlmsghdr
*
nlh
;
unsigned
char
*
b
=
skb
->
tail
;
struct
ip_stats
ipstats
;
unsigned
long
*
array
;
int
i
,
num
;
nlh
=
NLMSG_PUT
(
skb
,
pid
,
seq
,
event
,
sizeof
(
*
r
));
if
(
pid
)
nlh
->
nlmsg_flags
|=
NLM_F_MULTI
;
r
=
NLMSG_DATA
(
nlh
);
r
->
ipstats_family
=
AF_INET6
;
r
->
ipstats_ifindex
=
0
;
num
=
offsetof
(
struct
ip_stats
,
__pad
)
/
sizeof
(
unsigned
long
);
memset
(
&
ipstats
,
0
,
sizeof
(
struct
ip_stats
));
array
=
(
unsigned
long
*
)
&
ipstats
;
if
(
idev
==
NULL
)
{
/* fill IP mibs system statistics */
RTA_PUT
(
skb
,
IPSTATS_IFNAME
,
3
,
"all"
);
for
(
i
=
0
;
i
<
num
;
i
++
,
array
++
)
{
*
array
=
fold_field
((
void
**
)
ipv6_stats
,
i
*
(
sizeof
(
unsigned
long
)));
}
}
else
{
/* fill IP mibs interface statistics */
r
->
ipstats_ifindex
=
idev
->
dev
->
ifindex
;
RTA_PUT
(
skb
,
IPSTATS_IFNAME
,
strlen
(
idev
->
dev
->
name
)
+
1
,
idev
->
dev
->
name
);
for
(
i
=
0
;
i
<
num
;
i
++
,
array
++
)
{
*
array
=
fold_field
((
void
**
)
idev
->
stats
.
ipv6
,
i
*
(
sizeof
(
unsigned
long
)));
}
}
RTA_PUT
(
skb
,
IPSTATS_COUNTERS
,
sizeof
(
struct
ip_stats
),
&
ipstats
);
nlh
->
nlmsg_len
=
skb
->
tail
-
b
;
return
skb
->
len
;
nlmsg_failure:
rtattr_failure:
skb_trim
(
skb
,
b
-
skb
->
data
);
return
-
1
;
}
static
int
inet6_dump_ipstats
(
struct
sk_buff
*
skb
,
struct
netlink_callback
*
cb
)
{
int
err
,
idx
=
0
;
int
s_idx
=
cb
->
args
[
0
];
struct
net_device
*
dev
;
struct
inet6_dev
*
idev
;
/* fill IP mibs system statistics */
inet6_fill_ipstats
(
skb
,
NULL
,
NETLINK_CB
(
cb
->
skb
).
pid
,
cb
->
nlh
->
nlmsg_seq
,
RTM_NEWIPSTATS
);
idx
+=
1
;
/* fill IP mibs interface statistics */
read_lock
(
&
dev_base_lock
);
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
,
idx
++
)
{
if
(
idx
<
s_idx
)
continue
;
if
((
idev
=
in6_dev_get
(
dev
))
==
NULL
)
continue
;
err
=
inet6_fill_ipstats
(
skb
,
idev
,
NETLINK_CB
(
cb
->
skb
).
pid
,
cb
->
nlh
->
nlmsg_seq
,
RTM_NEWIPSTATS
);
in6_dev_put
(
idev
);
if
(
err
<=
0
)
break
;
}
read_unlock
(
&
dev_base_lock
);
cb
->
args
[
0
]
=
idx
;
return
skb
->
len
;
}
static
struct
rtnetlink_link
inet6_rtnetlink_table
[
RTM_MAX
-
RTM_BASE
+
1
]
=
{
static
struct
rtnetlink_link
inet6_rtnetlink_table
[
RTM_MAX
-
RTM_BASE
+
1
]
=
{
[
RTM_GETLINK
-
RTM_BASE
]
=
{
.
dumpit
=
inet6_dump_ifinfo
,
},
[
RTM_GETLINK
-
RTM_BASE
]
=
{
.
dumpit
=
inet6_dump_ifinfo
,
},
[
RTM_NEWADDR
-
RTM_BASE
]
=
{
.
doit
=
inet6_rtm_newaddr
,
},
[
RTM_NEWADDR
-
RTM_BASE
]
=
{
.
doit
=
inet6_rtm_newaddr
,
},
...
@@ -3069,7 +2974,6 @@ static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
...
@@ -3069,7 +2974,6 @@ static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
[
RTM_DELROUTE
-
RTM_BASE
]
=
{
.
doit
=
inet6_rtm_delroute
,
},
[
RTM_DELROUTE
-
RTM_BASE
]
=
{
.
doit
=
inet6_rtm_delroute
,
},
[
RTM_GETROUTE
-
RTM_BASE
]
=
{
.
doit
=
inet6_rtm_getroute
,
[
RTM_GETROUTE
-
RTM_BASE
]
=
{
.
doit
=
inet6_rtm_getroute
,
.
dumpit
=
inet6_dump_fib
,
},
.
dumpit
=
inet6_dump_fib
,
},
[
RTM_GETIPSTATS
-
RTM_BASE
]
=
{
.
dumpit
=
inet6_dump_ipstats
,
},
};
};
static
void
ipv6_ifa_notify
(
int
event
,
struct
inet6_ifaddr
*
ifp
)
static
void
ipv6_ifa_notify
(
int
event
,
struct
inet6_ifaddr
*
ifp
)
...
...
net/ipv6/af_inet6.c
View file @
cf8cd3d1
...
@@ -670,9 +670,6 @@ static int __init init_ipv6_mibs(void)
...
@@ -670,9 +670,6 @@ static int __init init_ipv6_mibs(void)
if
(
snmp6_mib_init
((
void
**
)
ipv6_statistics
,
sizeof
(
struct
ipv6_mib
),
if
(
snmp6_mib_init
((
void
**
)
ipv6_statistics
,
sizeof
(
struct
ipv6_mib
),
__alignof__
(
struct
ipv6_mib
))
<
0
)
__alignof__
(
struct
ipv6_mib
))
<
0
)
goto
err_ip_mib
;
goto
err_ip_mib
;
if
(
snmp6_mib_init
((
void
**
)
ipv6_stats
,
sizeof
(
struct
ip_stats
),
__alignof__
(
struct
ip_stats
))
<
0
)
goto
err_ip6_mib
;
if
(
snmp6_mib_init
((
void
**
)
icmpv6_statistics
,
sizeof
(
struct
icmpv6_mib
),
if
(
snmp6_mib_init
((
void
**
)
icmpv6_statistics
,
sizeof
(
struct
icmpv6_mib
),
__alignof__
(
struct
ipv6_mib
))
<
0
)
__alignof__
(
struct
ipv6_mib
))
<
0
)
goto
err_icmp_mib
;
goto
err_icmp_mib
;
...
@@ -684,8 +681,6 @@ static int __init init_ipv6_mibs(void)
...
@@ -684,8 +681,6 @@ static int __init init_ipv6_mibs(void)
err_udp_mib:
err_udp_mib:
snmp6_mib_free
((
void
**
)
icmpv6_statistics
);
snmp6_mib_free
((
void
**
)
icmpv6_statistics
);
err_icmp_mib:
err_icmp_mib:
snmp6_mib_free
((
void
**
)
ipv6_stats
);
err_ip6_mib:
snmp6_mib_free
((
void
**
)
ipv6_statistics
);
snmp6_mib_free
((
void
**
)
ipv6_statistics
);
err_ip_mib:
err_ip_mib:
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -695,7 +690,6 @@ static int __init init_ipv6_mibs(void)
...
@@ -695,7 +690,6 @@ static int __init init_ipv6_mibs(void)
static
void
cleanup_ipv6_mibs
(
void
)
static
void
cleanup_ipv6_mibs
(
void
)
{
{
snmp6_mib_free
((
void
**
)
ipv6_statistics
);
snmp6_mib_free
((
void
**
)
ipv6_statistics
);
snmp6_mib_free
((
void
**
)
ipv6_stats
);
snmp6_mib_free
((
void
**
)
icmpv6_statistics
);
snmp6_mib_free
((
void
**
)
icmpv6_statistics
);
snmp6_mib_free
((
void
**
)
udp_stats_in6
);
snmp6_mib_free
((
void
**
)
udp_stats_in6
);
}
}
...
...
net/ipv6/exthdrs.c
View file @
cf8cd3d1
...
@@ -156,15 +156,10 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -156,15 +156,10 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
{
{
struct
sk_buff
*
skb
=
*
skbp
;
struct
sk_buff
*
skb
=
*
skbp
;
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
likely
(
skb
->
dev
))
idev
=
__in6_dev_get
(
skb
->
dev
);
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
8
)
||
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
)))
{
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
((
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
)))
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
1
;
return
-
1
;
}
}
...
@@ -178,7 +173,6 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -178,7 +173,6 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
}
}
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
return
-
1
;
return
-
1
;
}
}
...
@@ -230,15 +224,10 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -230,15 +224,10 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
struct
ipv6_rt_hdr
*
hdr
;
struct
ipv6_rt_hdr
*
hdr
;
struct
rt0_hdr
*
rthdr
;
struct
rt0_hdr
*
rthdr
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
likely
(
skb
->
dev
))
idev
=
__in6_dev_get
(
skb
->
dev
);
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
8
)
||
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
)))
{
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
((
skb
->
h
.
raw
[
1
]
+
1
)
<<
3
)))
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
1
;
return
-
1
;
}
}
...
@@ -248,7 +237,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -248,7 +237,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if
(
ipv6_addr_is_multicast
(
&
skb
->
nh
.
ipv6h
->
daddr
)
||
if
(
ipv6_addr_is_multicast
(
&
skb
->
nh
.
ipv6h
->
daddr
)
||
skb
->
pkt_type
!=
PACKET_HOST
)
{
skb
->
pkt_type
!=
PACKET_HOST
)
{
IP6_INC_STATS_BH
(
Ip6InAddrErrors
);
IP6_INC_STATS_BH
(
Ip6InAddrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInAddrErrors
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
1
;
return
-
1
;
}
}
...
@@ -265,14 +253,12 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -265,14 +253,12 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if
(
hdr
->
type
!=
IPV6_SRCRT_TYPE_0
)
{
if
(
hdr
->
type
!=
IPV6_SRCRT_TYPE_0
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
&
hdr
->
type
)
-
skb
->
nh
.
raw
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
&
hdr
->
type
)
-
skb
->
nh
.
raw
);
return
-
1
;
return
-
1
;
}
}
if
(
hdr
->
hdrlen
&
0x01
)
{
if
(
hdr
->
hdrlen
&
0x01
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
&
hdr
->
hdrlen
)
-
skb
->
nh
.
raw
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
&
hdr
->
hdrlen
)
-
skb
->
nh
.
raw
);
return
-
1
;
return
-
1
;
}
}
...
@@ -286,7 +272,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -286,7 +272,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if
(
hdr
->
segments_left
>
n
)
{
if
(
hdr
->
segments_left
>
n
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
&
hdr
->
segments_left
)
-
skb
->
nh
.
raw
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
&
hdr
->
segments_left
)
-
skb
->
nh
.
raw
);
return
-
1
;
return
-
1
;
}
}
...
@@ -299,8 +284,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -299,8 +284,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
kfree_skb
(
skb
);
kfree_skb
(
skb
);
/* the copy is a forwarded packet */
/* the copy is a forwarded packet */
if
(
skb2
==
NULL
)
{
if
(
skb2
==
NULL
)
{
IP6_INC_STATS_BH
(
Ip6OutDiscards
);
IP6_INC_STATS_BH
(
Ip6OutDiscards
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsOutDiscards
);
return
-
1
;
return
-
1
;
}
}
*
skbp
=
skb
=
skb2
;
*
skbp
=
skb
=
skb2
;
...
@@ -319,7 +303,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -319,7 +303,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if
(
ipv6_addr_is_multicast
(
addr
))
{
if
(
ipv6_addr_is_multicast
(
addr
))
{
IP6_INC_STATS_BH
(
Ip6InAddrErrors
);
IP6_INC_STATS_BH
(
Ip6InAddrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInAddrErrors
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
1
;
return
-
1
;
}
}
...
@@ -337,7 +320,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -337,7 +320,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
if
(
skb
->
dst
->
dev
->
flags
&
IFF_LOOPBACK
)
{
if
(
skb
->
dst
->
dev
->
flags
&
IFF_LOOPBACK
)
{
if
(
skb
->
nh
.
ipv6h
->
hop_limit
<=
1
)
{
if
(
skb
->
nh
.
ipv6h
->
hop_limit
<=
1
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_send
(
skb
,
ICMPV6_TIME_EXCEED
,
ICMPV6_EXC_HOPLIMIT
,
icmpv6_send
(
skb
,
ICMPV6_TIME_EXCEED
,
ICMPV6_EXC_HOPLIMIT
,
0
,
skb
->
dev
);
0
,
skb
->
dev
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
...
@@ -450,36 +432,28 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
...
@@ -450,36 +432,28 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
static
int
ipv6_hop_jumbo
(
struct
sk_buff
*
skb
,
int
optoff
)
static
int
ipv6_hop_jumbo
(
struct
sk_buff
*
skb
,
int
optoff
)
{
{
u32
pkt_len
;
u32
pkt_len
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
likely
(
skb
->
dev
))
idev
=
__in6_dev_get
(
skb
->
dev
);
if
(
skb
->
nh
.
raw
[
optoff
+
1
]
!=
4
||
(
optoff
&
3
)
!=
2
)
{
if
(
skb
->
nh
.
raw
[
optoff
+
1
]
!=
4
||
(
optoff
&
3
)
!=
2
)
{
LIMIT_NETDEBUG
(
LIMIT_NETDEBUG
(
printk
(
KERN_DEBUG
"ipv6_hop_jumbo: wrong jumbo opt length/alignment %d
\n
"
,
skb
->
nh
.
raw
[
optoff
+
1
]));
printk
(
KERN_DEBUG
"ipv6_hop_jumbo: wrong jumbo opt length/alignment %d
\n
"
,
skb
->
nh
.
raw
[
optoff
+
1
]));
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
goto
drop
;
goto
drop
;
}
}
pkt_len
=
ntohl
(
*
(
u32
*
)(
skb
->
nh
.
raw
+
optoff
+
2
));
pkt_len
=
ntohl
(
*
(
u32
*
)(
skb
->
nh
.
raw
+
optoff
+
2
));
if
(
pkt_len
<=
IPV6_MAXPLEN
)
{
if
(
pkt_len
<=
IPV6_MAXPLEN
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
optoff
+
2
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
optoff
+
2
);
return
0
;
return
0
;
}
}
if
(
skb
->
nh
.
ipv6h
->
payload_len
)
{
if
(
skb
->
nh
.
ipv6h
->
payload_len
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
optoff
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
optoff
);
return
0
;
return
0
;
}
}
if
(
pkt_len
>
skb
->
len
-
sizeof
(
struct
ipv6hdr
))
{
if
(
pkt_len
>
skb
->
len
-
sizeof
(
struct
ipv6hdr
))
{
IP6_INC_STATS_BH
(
Ip6InTruncatedPkts
);
IP6_INC_STATS_BH
(
Ip6InTruncatedPkts
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInTruncatedPkts
);
goto
drop
;
goto
drop
;
}
}
if
(
pkt_len
+
sizeof
(
struct
ipv6hdr
)
<
skb
->
len
)
{
if
(
pkt_len
+
sizeof
(
struct
ipv6hdr
)
<
skb
->
len
)
{
...
...
net/ipv6/icmp.c
View file @
cf8cd3d1
...
@@ -158,7 +158,6 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
...
@@ -158,7 +158,6 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
{
{
struct
dst_entry
*
dst
;
struct
dst_entry
*
dst
;
int
res
=
0
;
int
res
=
0
;
struct
inet6_dev
*
idev
=
NULL
;
/* Informational messages are not limited. */
/* Informational messages are not limited. */
if
(
type
&
ICMPV6_INFOMSG_MASK
)
if
(
type
&
ICMPV6_INFOMSG_MASK
)
...
@@ -174,12 +173,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
...
@@ -174,12 +173,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
* this lookup should be more aggressive (not longer than timeout).
* this lookup should be more aggressive (not longer than timeout).
*/
*/
dst
=
ip6_route_output
(
sk
,
fl
);
dst
=
ip6_route_output
(
sk
,
fl
);
/* idev reference for IP MIBs */
if
(
likely
(
dst
->
dev
))
idev
=
in6_dev_get
(
dst
->
dev
);
if
(
dst
->
error
)
{
if
(
dst
->
error
)
{
IP6_INC_STATS
(
Ip6OutNoRoutes
);
IP6_INC_STATS
(
Ip6OutNoRoutes
);
IPV6_INC_STATS
(
idev
,
ipStatsOutNoRoutes
);
}
else
if
(
dst
->
dev
&&
(
dst
->
dev
->
flags
&
IFF_LOOPBACK
))
{
}
else
if
(
dst
->
dev
&&
(
dst
->
dev
->
flags
&
IFF_LOOPBACK
))
{
res
=
1
;
res
=
1
;
}
else
{
}
else
{
...
@@ -192,9 +187,6 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
...
@@ -192,9 +187,6 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
res
=
xrlim_allow
(
dst
,
tmo
);
res
=
xrlim_allow
(
dst
,
tmo
);
}
}
/* release the idev reference for IP MIBs */
if
(
likely
(
idev
))
in6_dev_put
(
idev
);
dst_release
(
dst
);
dst_release
(
dst
);
return
res
;
return
res
;
}
}
...
...
net/ipv6/ip6_input.c
View file @
cf8cd3d1
...
@@ -60,22 +60,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -60,22 +60,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
{
{
struct
ipv6hdr
*
hdr
;
struct
ipv6hdr
*
hdr
;
u32
pkt_len
;
u32
pkt_len
;
struct
inet6_dev
*
idev
=
NULL
;
int
err
=
0
;
/* idev reference for input IP MIBs */
if
(
likely
(
skb
->
dev
))
idev
=
in6_dev_get
(
skb
->
dev
);
if
(
skb
->
pkt_type
==
PACKET_OTHERHOST
)
if
(
skb
->
pkt_type
==
PACKET_OTHERHOST
)
goto
drop
;
goto
drop
;
IP6_INC_STATS_BH
(
Ip6InReceives
);
IP6_INC_STATS_BH
(
Ip6InReceives
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInReceives
);
if
((
skb
=
skb_share_check
(
skb
,
GFP_ATOMIC
))
==
NULL
)
{
if
((
skb
=
skb_share_check
(
skb
,
GFP_ATOMIC
))
==
NULL
)
{
IP6_INC_STATS_BH
(
Ip6InDiscards
);
IP6_INC_STATS_BH
(
Ip6InDiscards
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDiscards
);
goto
out
;
goto
out
;
}
}
...
@@ -89,7 +81,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -89,7 +81,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
struct
ipv6hdr
)))
{
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
struct
ipv6hdr
)))
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
goto
drop
;
goto
drop
;
}
}
...
@@ -99,7 +90,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -99,7 +90,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
goto
err
;
goto
err
;
pkt_len
=
ntohs
(
hdr
->
payload_len
);
pkt_len
=
ntohs
(
hdr
->
payload_len
);
IPV6_ADD_STATS_BH
(
idev
,
ipStatsInOctets
,
skb
->
len
);
/* pkt_len may be zero if Jumbo payload option is present */
/* pkt_len may be zero if Jumbo payload option is present */
if
(
pkt_len
||
hdr
->
nexthdr
!=
NEXTHDR_HOP
)
{
if
(
pkt_len
||
hdr
->
nexthdr
!=
NEXTHDR_HOP
)
{
...
@@ -108,7 +98,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -108,7 +98,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if
(
pkt_len
+
sizeof
(
struct
ipv6hdr
)
<
skb
->
len
)
{
if
(
pkt_len
+
sizeof
(
struct
ipv6hdr
)
<
skb
->
len
)
{
if
(
__pskb_trim
(
skb
,
pkt_len
+
sizeof
(
struct
ipv6hdr
))){
if
(
__pskb_trim
(
skb
,
pkt_len
+
sizeof
(
struct
ipv6hdr
))){
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
goto
drop
;
goto
drop
;
}
}
hdr
=
skb
->
nh
.
ipv6h
;
hdr
=
skb
->
nh
.
ipv6h
;
...
@@ -121,26 +110,20 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
...
@@ -121,26 +110,20 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
skb
->
h
.
raw
=
(
u8
*
)(
hdr
+
1
);
skb
->
h
.
raw
=
(
u8
*
)(
hdr
+
1
);
if
(
ipv6_parse_hopopts
(
skb
,
offsetof
(
struct
ipv6hdr
,
nexthdr
))
<
0
)
{
if
(
ipv6_parse_hopopts
(
skb
,
offsetof
(
struct
ipv6hdr
,
nexthdr
))
<
0
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
return
0
;
goto
out
;
}
}
hdr
=
skb
->
nh
.
ipv6h
;
hdr
=
skb
->
nh
.
ipv6h
;
}
}
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_PRE_ROUTING
,
skb
,
dev
,
NULL
,
ip6_rcv_finish
);
return
NF_HOOK
(
PF_INET6
,
NF_IP6_PRE_ROUTING
,
skb
,
dev
,
NULL
,
ip6_rcv_finish
);
goto
out
;
truncated:
truncated:
IP6_INC_STATS_BH
(
Ip6InTruncatedPkts
);
IP6_INC_STATS_BH
(
Ip6InTruncatedPkts
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInTruncatedPkts
);
err:
err:
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
drop:
drop:
kfree_skb
(
skb
);
kfree_skb
(
skb
);
out:
out:
if
(
likely
(
idev
))
return
0
;
in6_dev_put
(
idev
);
return
err
;
}
}
/*
/*
...
@@ -156,10 +139,6 @@ static inline int ip6_input_finish(struct sk_buff *skb)
...
@@ -156,10 +139,6 @@ static inline int ip6_input_finish(struct sk_buff *skb)
int
nexthdr
;
int
nexthdr
;
u8
hash
;
u8
hash
;
int
cksum_sub
=
0
;
int
cksum_sub
=
0
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
skb
->
dev
)
idev
=
__in6_dev_get
(
skb
->
dev
);
skb
->
h
.
raw
=
skb
->
nh
.
raw
+
sizeof
(
struct
ipv6hdr
);
skb
->
h
.
raw
=
skb
->
nh
.
raw
+
sizeof
(
struct
ipv6hdr
);
...
@@ -214,20 +193,16 @@ static inline int ip6_input_finish(struct sk_buff *skb)
...
@@ -214,20 +193,16 @@ static inline int ip6_input_finish(struct sk_buff *skb)
ret
=
ipprot
->
handler
(
&
skb
,
&
nhoff
);
ret
=
ipprot
->
handler
(
&
skb
,
&
nhoff
);
if
(
ret
>
0
)
if
(
ret
>
0
)
goto
resubmit
;
goto
resubmit
;
else
if
(
ret
==
0
)
{
else
if
(
ret
==
0
)
IP6_INC_STATS_BH
(
Ip6InDelivers
);
IP6_INC_STATS_BH
(
Ip6InDelivers
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDelivers
);
}
}
else
{
}
else
{
if
(
!
raw_sk
)
{
if
(
!
raw_sk
)
{
if
(
xfrm6_policy_check
(
NULL
,
XFRM_POLICY_IN
,
skb
))
{
if
(
xfrm6_policy_check
(
NULL
,
XFRM_POLICY_IN
,
skb
))
{
IP6_INC_STATS_BH
(
Ip6InUnknownProtos
);
IP6_INC_STATS_BH
(
Ip6InUnknownProtos
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInUnknownProtos
);
icmpv6_param_prob
(
skb
,
ICMPV6_UNK_NEXTHDR
,
nhoff
);
icmpv6_param_prob
(
skb
,
ICMPV6_UNK_NEXTHDR
,
nhoff
);
}
}
}
else
{
}
else
{
IP6_INC_STATS_BH
(
Ip6InDelivers
);
IP6_INC_STATS_BH
(
Ip6InDelivers
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDelivers
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
}
}
}
}
...
@@ -236,7 +211,6 @@ static inline int ip6_input_finish(struct sk_buff *skb)
...
@@ -236,7 +211,6 @@ static inline int ip6_input_finish(struct sk_buff *skb)
discard:
discard:
IP6_INC_STATS_BH
(
Ip6InDiscards
);
IP6_INC_STATS_BH
(
Ip6InDiscards
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDiscards
);
rcu_read_unlock
();
rcu_read_unlock
();
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
0
;
return
0
;
...
@@ -252,13 +226,8 @@ int ip6_mc_input(struct sk_buff *skb)
...
@@ -252,13 +226,8 @@ int ip6_mc_input(struct sk_buff *skb)
{
{
struct
ipv6hdr
*
hdr
;
struct
ipv6hdr
*
hdr
;
int
deliver
;
int
deliver
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
skb
->
dev
)
idev
=
__in6_dev_get
(
skb
->
dev
);
IP6_INC_STATS_BH
(
Ip6InMcastPkts
);
IP6_INC_STATS_BH
(
Ip6InMcastPkts
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInMcastPkts
);
IPV6_ADD_STATS_BH
(
idev
,
ipStatsInMcastOctets
,
skb
->
len
);
hdr
=
skb
->
nh
.
ipv6h
;
hdr
=
skb
->
nh
.
ipv6h
;
deliver
=
likely
(
!
(
skb
->
dev
->
flags
&
(
IFF_PROMISC
|
IFF_ALLMULTI
)))
||
deliver
=
likely
(
!
(
skb
->
dev
->
flags
&
(
IFF_PROMISC
|
IFF_ALLMULTI
)))
||
...
...
net/ipv6/ip6_output.c
View file @
cf8cd3d1
...
@@ -74,10 +74,6 @@ static inline int ip6_output_finish(struct sk_buff *skb)
...
@@ -74,10 +74,6 @@ static inline int ip6_output_finish(struct sk_buff *skb)
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
hh_cache
*
hh
=
dst
->
hh
;
struct
hh_cache
*
hh
=
dst
->
hh
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
likely
(
skb
->
dev
))
idev
=
__in6_dev_get
(
skb
->
dev
);
if
(
hh
)
{
if
(
hh
)
{
int
hh_alen
;
int
hh_alen
;
...
@@ -87,15 +83,11 @@ static inline int ip6_output_finish(struct sk_buff *skb)
...
@@ -87,15 +83,11 @@ static inline int ip6_output_finish(struct sk_buff *skb)
memcpy
(
skb
->
data
-
hh_alen
,
hh
->
hh_data
,
hh_alen
);
memcpy
(
skb
->
data
-
hh_alen
,
hh
->
hh_data
,
hh_alen
);
read_unlock_bh
(
&
hh
->
hh_lock
);
read_unlock_bh
(
&
hh
->
hh_lock
);
skb_push
(
skb
,
hh
->
hh_len
);
skb_push
(
skb
,
hh
->
hh_len
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsOutTransmits
);
return
hh
->
hh_output
(
skb
);
return
hh
->
hh_output
(
skb
);
}
else
if
(
dst
->
neighbour
)
{
}
else
if
(
dst
->
neighbour
)
IPV6_INC_STATS_BH
(
idev
,
ipStatsOutTransmits
);
return
dst
->
neighbour
->
output
(
skb
);
return
dst
->
neighbour
->
output
(
skb
);
}
IP6_INC_STATS_BH
(
Ip6OutNoRoutes
);
IP6_INC_STATS_BH
(
Ip6OutNoRoutes
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsOutDiscards
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -119,12 +111,9 @@ int ip6_output2(struct sk_buff *skb)
...
@@ -119,12 +111,9 @@ int ip6_output2(struct sk_buff *skb)
{
{
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
net_device
*
dev
=
dst
->
dev
;
struct
net_device
*
dev
=
dst
->
dev
;
struct
inet6_dev
*
idev
=
NULL
;
skb
->
protocol
=
htons
(
ETH_P_IPV6
);
skb
->
protocol
=
htons
(
ETH_P_IPV6
);
skb
->
dev
=
dev
;
skb
->
dev
=
dev
;
if
(
likely
(
dev
))
idev
=
__in6_dev_get
(
dev
);
if
(
ipv6_addr_is_multicast
(
&
skb
->
nh
.
ipv6h
->
daddr
))
{
if
(
ipv6_addr_is_multicast
(
&
skb
->
nh
.
ipv6h
->
daddr
))
{
struct
ipv6_pinfo
*
np
=
skb
->
sk
?
inet6_sk
(
skb
->
sk
)
:
NULL
;
struct
ipv6_pinfo
*
np
=
skb
->
sk
?
inet6_sk
(
skb
->
sk
)
:
NULL
;
...
@@ -144,15 +133,12 @@ int ip6_output2(struct sk_buff *skb)
...
@@ -144,15 +133,12 @@ int ip6_output2(struct sk_buff *skb)
if
(
skb
->
nh
.
ipv6h
->
hop_limit
==
0
)
{
if
(
skb
->
nh
.
ipv6h
->
hop_limit
==
0
)
{
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
0
;
return
0
;
}
}
}
}
IP6_INC_STATS
(
Ip6OutMcastPkts
);
IP6_INC_STATS
(
Ip6OutMcastPkts
);
IPV6_INC_STATS
(
idev
,
ipStatsOutMcastPkts
);
IPV6_ADD_STATS
(
idev
,
ipStatsOutMcastOctets
,
skb
->
len
);
}
}
return
NF_HOOK
(
PF_INET6
,
NF_IP6_POST_ROUTING
,
skb
,
NULL
,
skb
->
dev
,
ip6_output_finish
);
return
NF_HOOK
(
PF_INET6
,
NF_IP6_POST_ROUTING
,
skb
,
NULL
,
skb
->
dev
,
ip6_output_finish
);
...
@@ -171,7 +157,6 @@ int ip6_route_me_harder(struct sk_buff *skb)
...
@@ -171,7 +157,6 @@ int ip6_route_me_harder(struct sk_buff *skb)
{
{
struct
ipv6hdr
*
iph
=
skb
->
nh
.
ipv6h
;
struct
ipv6hdr
*
iph
=
skb
->
nh
.
ipv6h
;
struct
dst_entry
*
dst
;
struct
dst_entry
*
dst
;
struct
inet6_dev
*
idev
=
NULL
;
struct
flowi
fl
=
{
struct
flowi
fl
=
{
.
oif
=
skb
->
sk
?
skb
->
sk
->
sk_bound_dev_if
:
0
,
.
oif
=
skb
->
sk
?
skb
->
sk
->
sk_bound_dev_if
:
0
,
.
nl_u
=
.
nl_u
=
...
@@ -182,26 +167,18 @@ int ip6_route_me_harder(struct sk_buff *skb)
...
@@ -182,26 +167,18 @@ int ip6_route_me_harder(struct sk_buff *skb)
};
};
dst
=
ip6_route_output
(
skb
->
sk
,
&
fl
);
dst
=
ip6_route_output
(
skb
->
sk
,
&
fl
);
if
(
likely
(
skb
->
dev
))
idev
=
__in6_dev_get
(
skb
->
dev
);
if
(
dst
->
error
)
{
if
(
dst
->
error
)
{
IP6_INC_STATS
(
Ip6OutNoRoutes
);
IP6_INC_STATS
(
Ip6OutNoRoutes
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsOutNoRoutes
);
LIMIT_NETDEBUG
(
LIMIT_NETDEBUG
(
printk
(
KERN_DEBUG
"ip6_route_me_harder: No more route.
\n
"
));
printk
(
KERN_DEBUG
"ip6_route_me_harder: No more route.
\n
"
));
dst_release
(
dst
);
dst_release
(
dst
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
/* drop the IP MIBs reference for old idev */
if
(
likely
(
skb
->
dst
))
in6_dev_put
(
__in6_dev_get
(
skb
->
dst
->
dev
));
/* Drop old route. */
/* Drop old route. */
dst_release
(
skb
->
dst
);
dst_release
(
skb
->
dst
);
/* IP MIBs refer to the new dst idev */
if
(
likely
(
dst
->
dev
))
idev
=
in6_dev_get
(
dst
->
dev
);
skb
->
dst
=
dst
;
skb
->
dst
=
dst
;
return
0
;
return
0
;
}
}
...
@@ -235,13 +212,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
...
@@ -235,13 +212,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
int
seg_len
=
skb
->
len
;
int
seg_len
=
skb
->
len
;
int
hlimit
;
int
hlimit
;
u32
mtu
;
u32
mtu
;
struct
inet6_dev
*
idev
=
NULL
;
int
errno
=
0
;
/* idev reference for IP MIBs */
if
(
likely
(
skb
->
dst
))
idev
=
in6_dev_get
(
skb
->
dst
->
dev
);
if
(
opt
)
{
if
(
opt
)
{
int
head_room
;
int
head_room
;
...
@@ -258,9 +229,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
...
@@ -258,9 +229,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
skb
=
skb2
;
skb
=
skb2
;
if
(
skb
==
NULL
)
{
if
(
skb
==
NULL
)
{
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
return
-
ENOBUFS
;
errno
=
-
ENOBUFS
;
goto
out
;
}
}
if
(
sk
)
if
(
sk
)
skb_set_owner_w
(
skb
,
sk
);
skb_set_owner_w
(
skb
,
sk
);
...
@@ -294,10 +263,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
...
@@ -294,10 +263,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
mtu
=
dst_pmtu
(
dst
);
mtu
=
dst_pmtu
(
dst
);
if
((
skb
->
len
<=
mtu
)
||
ipfragok
)
{
if
((
skb
->
len
<=
mtu
)
||
ipfragok
)
{
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
return
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
ip6_maybe_reroute
);
IPV6_ADD_STATS
(
idev
,
ipStatsOutOctets
,
skb
->
len
);
errno
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
ip6_maybe_reroute
);
goto
out
;
}
}
if
(
net_ratelimit
())
if
(
net_ratelimit
())
...
@@ -305,13 +271,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
...
@@ -305,13 +271,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
skb
->
dev
=
dst
->
dev
;
skb
->
dev
=
dst
->
dev
;
icmpv6_send
(
skb
,
ICMPV6_PKT_TOOBIG
,
0
,
mtu
,
skb
->
dev
);
icmpv6_send
(
skb
,
ICMPV6_PKT_TOOBIG
,
0
,
mtu
,
skb
->
dev
);
IP6_INC_STATS
(
Ip6FragFails
);
IP6_INC_STATS
(
Ip6FragFails
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
errno
=
-
EMSGSIZE
;
return
-
EMSGSIZE
;
out:
if
(
likely
(
idev
))
in6_dev_put
(
idev
);
return
errno
;
}
}
/*
/*
...
@@ -386,22 +347,12 @@ int ip6_forward(struct sk_buff *skb)
...
@@ -386,22 +347,12 @@ int ip6_forward(struct sk_buff *skb)
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
ipv6hdr
*
hdr
=
skb
->
nh
.
ipv6h
;
struct
ipv6hdr
*
hdr
=
skb
->
nh
.
ipv6h
;
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
struct
inet6_dev
*
idev
=
NULL
;
int
errno
=
0
;
/* idev reference for IP MIBs*/
if
(
likely
(
dst
))
idev
=
in6_dev_get
(
dst
->
dev
);
if
(
ipv6_devconf
.
forwarding
==
0
)
{
if
(
ipv6_devconf
.
forwarding
==
0
)
errno
=
-
EINVAL
;
goto
error
;
goto
error
;
}
if
(
!
xfrm6_policy_check
(
NULL
,
XFRM_POLICY_FWD
,
skb
))
{
if
(
!
xfrm6_policy_check
(
NULL
,
XFRM_POLICY_FWD
,
skb
))
{
IP6_INC_STATS
(
Ip6InDiscards
);
IP6_INC_STATS
(
Ip6InDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsInDiscards
);
errno
=
-
EINVAL
;
goto
drop
;
goto
drop
;
}
}
...
@@ -423,7 +374,7 @@ int ip6_forward(struct sk_buff *skb)
...
@@ -423,7 +374,7 @@ int ip6_forward(struct sk_buff *skb)
if
(
opt
->
ra
)
{
if
(
opt
->
ra
)
{
u8
*
ptr
=
skb
->
nh
.
raw
+
opt
->
ra
;
u8
*
ptr
=
skb
->
nh
.
raw
+
opt
->
ra
;
if
(
ip6_call_ra_chain
(
skb
,
(
ptr
[
2
]
<<
8
)
+
ptr
[
3
]))
if
(
ip6_call_ra_chain
(
skb
,
(
ptr
[
2
]
<<
8
)
+
ptr
[
3
]))
goto
out
;
return
0
;
}
}
/*
/*
...
@@ -434,17 +385,13 @@ int ip6_forward(struct sk_buff *skb)
...
@@ -434,17 +385,13 @@ int ip6_forward(struct sk_buff *skb)
skb
->
dev
=
dst
->
dev
;
skb
->
dev
=
dst
->
dev
;
icmpv6_send
(
skb
,
ICMPV6_TIME_EXCEED
,
ICMPV6_EXC_HOPLIMIT
,
icmpv6_send
(
skb
,
ICMPV6_TIME_EXCEED
,
ICMPV6_EXC_HOPLIMIT
,
0
,
skb
->
dev
);
0
,
skb
->
dev
);
IP6_INC_STATS
(
Ip6InDiscards
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDiscards
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
errno
=
-
ETIMEDOUT
;
return
-
ETIMEDOUT
;
goto
out
;
}
}
if
(
!
xfrm6_route_forward
(
skb
))
{
if
(
!
xfrm6_route_forward
(
skb
))
{
IP6_INC_STATS
(
Ip6InDiscards
);
IP6_INC_STATS
(
Ip6InDiscards
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDiscards
);
errno
=
-
EINVAL
;
goto
drop
;
goto
drop
;
}
}
...
@@ -475,7 +422,6 @@ int ip6_forward(struct sk_buff *skb)
...
@@ -475,7 +422,6 @@ int ip6_forward(struct sk_buff *skb)
}
else
if
(
ipv6_addr_type
(
&
hdr
->
saddr
)
&
(
IPV6_ADDR_MULTICAST
|
IPV6_ADDR_LOOPBACK
}
else
if
(
ipv6_addr_type
(
&
hdr
->
saddr
)
&
(
IPV6_ADDR_MULTICAST
|
IPV6_ADDR_LOOPBACK
|
IPV6_ADDR_LINKLOCAL
))
{
|
IPV6_ADDR_LINKLOCAL
))
{
/* This check is security critical. */
/* This check is security critical. */
errno
=
-
EINVAL
;
goto
error
;
goto
error
;
}
}
...
@@ -485,16 +431,12 @@ int ip6_forward(struct sk_buff *skb)
...
@@ -485,16 +431,12 @@ int ip6_forward(struct sk_buff *skb)
icmpv6_send
(
skb
,
ICMPV6_PKT_TOOBIG
,
0
,
dst_pmtu
(
dst
),
skb
->
dev
);
icmpv6_send
(
skb
,
ICMPV6_PKT_TOOBIG
,
0
,
dst_pmtu
(
dst
),
skb
->
dev
);
IP6_INC_STATS_BH
(
Ip6InTooBigErrors
);
IP6_INC_STATS_BH
(
Ip6InTooBigErrors
);
IP6_INC_STATS_BH
(
Ip6FragFails
);
IP6_INC_STATS_BH
(
Ip6FragFails
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsOutFragFails
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
errno
=
-
EMSGSIZE
;
return
-
EMSGSIZE
;
goto
out
;
}
}
if
(
skb_cow
(
skb
,
dst
->
dev
->
hard_header_len
))
{
if
(
skb_cow
(
skb
,
dst
->
dev
->
hard_header_len
))
{
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDiscards
);
errno
=
-
EINVAL
;
goto
drop
;
goto
drop
;
}
}
...
@@ -505,18 +447,13 @@ int ip6_forward(struct sk_buff *skb)
...
@@ -505,18 +447,13 @@ int ip6_forward(struct sk_buff *skb)
hdr
->
hop_limit
--
;
hdr
->
hop_limit
--
;
IP6_INC_STATS_BH
(
Ip6OutForwDatagrams
);
IP6_INC_STATS_BH
(
Ip6OutForwDatagrams
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsOutForwDatagrams
);
return
NF_HOOK
(
PF_INET6
,
NF_IP6_FORWARD
,
skb
,
skb
->
dev
,
dst
->
dev
,
ip6_forward_finish
);
errno
=
NF_HOOK
(
PF_INET6
,
NF_IP6_FORWARD
,
skb
,
skb
->
dev
,
dst
->
dev
,
ip6_forward_finish
);
goto
out
;
error:
error:
IP6_INC_STATS_BH
(
Ip6InAddrErrors
);
IP6_INC_STATS_BH
(
Ip6InAddrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInAddrErrors
);
drop:
drop:
kfree_skb
(
skb
);
kfree_skb
(
skb
);
out:
return
-
EINVAL
;
if
(
likely
(
idev
))
in6_dev_put
(
idev
);
return
errno
;
}
}
static
void
ip6_copy_metadata
(
struct
sk_buff
*
to
,
struct
sk_buff
*
from
)
static
void
ip6_copy_metadata
(
struct
sk_buff
*
to
,
struct
sk_buff
*
from
)
...
@@ -587,11 +524,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
...
@@ -587,11 +524,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
u32
frag_id
=
0
;
u32
frag_id
=
0
;
int
ptr
,
offset
=
0
,
err
=
0
;
int
ptr
,
offset
=
0
,
err
=
0
;
u8
*
prevhdr
,
nexthdr
=
0
;
u8
*
prevhdr
,
nexthdr
=
0
;
struct
inet6_dev
*
idev
=
NULL
;
dev
=
rt
->
u
.
dst
.
dev
;
dev
=
rt
->
u
.
dst
.
dev
;
if
(
likely
(
dev
))
idev
=
__in6_dev_get
(
dev
);
hlen
=
ip6_find_1stfragopt
(
skb
,
&
prevhdr
);
hlen
=
ip6_find_1stfragopt
(
skb
,
&
prevhdr
);
nexthdr
=
*
prevhdr
;
nexthdr
=
*
prevhdr
;
...
@@ -630,7 +564,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
...
@@ -630,7 +564,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
tmp_hdr
=
kmalloc
(
hlen
,
GFP_ATOMIC
);
tmp_hdr
=
kmalloc
(
hlen
,
GFP_ATOMIC
);
if
(
!
tmp_hdr
)
{
if
(
!
tmp_hdr
)
{
IP6_INC_STATS
(
Ip6FragFails
);
IP6_INC_STATS
(
Ip6FragFails
);
IPV6_INC_STATS
(
idev
,
ipStatsOutFragFails
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
...
@@ -686,7 +619,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
...
@@ -686,7 +619,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
if
(
err
==
0
)
{
if
(
err
==
0
)
{
IP6_INC_STATS
(
Ip6FragOKs
);
IP6_INC_STATS
(
Ip6FragOKs
);
IPV6_INC_STATS
(
idev
,
ipStatsOutFragOKs
);
return
0
;
return
0
;
}
}
...
@@ -697,7 +629,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
...
@@ -697,7 +629,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
}
}
IP6_INC_STATS
(
Ip6FragFails
);
IP6_INC_STATS
(
Ip6FragFails
);
IPV6_INC_STATS
(
idev
,
ipStatsOutFragFails
);
return
err
;
return
err
;
}
}
...
@@ -731,7 +662,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
...
@@ -731,7 +662,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
if
((
frag
=
alloc_skb
(
len
+
hlen
+
sizeof
(
struct
frag_hdr
)
+
LL_RESERVED_SPACE
(
rt
->
u
.
dst
.
dev
),
GFP_ATOMIC
))
==
NULL
)
{
if
((
frag
=
alloc_skb
(
len
+
hlen
+
sizeof
(
struct
frag_hdr
)
+
LL_RESERVED_SPACE
(
rt
->
u
.
dst
.
dev
),
GFP_ATOMIC
))
==
NULL
)
{
NETDEBUG
(
printk
(
KERN_INFO
"IPv6: frag: no memory for new fragment!
\n
"
));
NETDEBUG
(
printk
(
KERN_INFO
"IPv6: frag: no memory for new fragment!
\n
"
));
IP6_INC_STATS
(
Ip6FragFails
);
IP6_INC_STATS
(
Ip6FragFails
);
IPV6_INC_STATS
(
idev
,
ipStatsOutFragFails
);
err
=
-
ENOMEM
;
err
=
-
ENOMEM
;
goto
fail
;
goto
fail
;
}
}
...
@@ -790,7 +720,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
...
@@ -790,7 +720,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
*/
*/
IP6_INC_STATS
(
Ip6FragCreates
);
IP6_INC_STATS
(
Ip6FragCreates
);
IPV6_INC_STATS
(
idev
,
ipStatsOutFragCreates
);
err
=
output
(
frag
);
err
=
output
(
frag
);
if
(
err
)
if
(
err
)
...
@@ -798,13 +727,11 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
...
@@ -798,13 +727,11 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
}
}
kfree_skb
(
skb
);
kfree_skb
(
skb
);
IP6_INC_STATS
(
Ip6FragOKs
);
IP6_INC_STATS
(
Ip6FragOKs
);
IPV6_INC_STATS
(
idev
,
ipStatsOutFragOKs
);
return
err
;
return
err
;
fail:
fail:
kfree_skb
(
skb
);
kfree_skb
(
skb
);
IP6_INC_STATS
(
Ip6FragFails
);
IP6_INC_STATS
(
Ip6FragFails
);
IPV6_INC_STATS
(
idev
,
ipStatsOutFragFails
);
return
err
;
return
err
;
}
}
...
@@ -895,7 +822,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
...
@@ -895,7 +822,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
int
err
;
int
err
;
int
offset
=
0
;
int
offset
=
0
;
int
csummode
=
CHECKSUM_NONE
;
int
csummode
=
CHECKSUM_NONE
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
flags
&
MSG_PROBE
)
if
(
flags
&
MSG_PROBE
)
return
0
;
return
0
;
...
@@ -1090,10 +1016,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
...
@@ -1090,10 +1016,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
return
0
;
return
0
;
error:
error:
inet
->
cork
.
length
-=
length
;
inet
->
cork
.
length
-=
length
;
if
(
likely
(
skb
->
dev
))
idev
=
__in6_dev_get
(
skb
->
dev
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
return
err
;
return
err
;
}
}
...
@@ -1110,7 +1033,6 @@ int ip6_push_pending_frames(struct sock *sk)
...
@@ -1110,7 +1033,6 @@ int ip6_push_pending_frames(struct sock *sk)
struct
flowi
*
fl
=
&
inet
->
cork
.
fl
;
struct
flowi
*
fl
=
&
inet
->
cork
.
fl
;
unsigned
char
proto
=
fl
->
proto
;
unsigned
char
proto
=
fl
->
proto
;
int
err
=
0
;
int
err
=
0
;
struct
inet6_dev
*
idev
=
NULL
;
if
((
skb
=
__skb_dequeue
(
&
sk
->
sk_write_queue
))
==
NULL
)
if
((
skb
=
__skb_dequeue
(
&
sk
->
sk_write_queue
))
==
NULL
)
goto
out
;
goto
out
;
...
@@ -1154,12 +1076,7 @@ int ip6_push_pending_frames(struct sock *sk)
...
@@ -1154,12 +1076,7 @@ int ip6_push_pending_frames(struct sock *sk)
ipv6_addr_copy
(
&
hdr
->
daddr
,
final_dst
);
ipv6_addr_copy
(
&
hdr
->
daddr
,
final_dst
);
skb
->
dst
=
dst_clone
(
&
rt
->
u
.
dst
);
skb
->
dst
=
dst_clone
(
&
rt
->
u
.
dst
);
/* idev reference for IP MIBs */
IP6_INC_STATS
(
Ip6OutRequests
);
if
(
likely
(
skb
->
dst
))
idev
=
in6_dev_get
(
skb
->
dst
->
dev
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
IPV6_ADD_STATS
(
idev
,
ipStatsOutOctets
,
skb
->
len
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
skb
->
dst
->
dev
,
dst_output
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
skb
->
dst
->
dev
,
dst_output
);
if
(
err
)
{
if
(
err
)
{
if
(
err
>
0
)
if
(
err
>
0
)
...
@@ -1179,8 +1096,6 @@ int ip6_push_pending_frames(struct sock *sk)
...
@@ -1179,8 +1096,6 @@ int ip6_push_pending_frames(struct sock *sk)
np
->
cork
.
rt
=
NULL
;
np
->
cork
.
rt
=
NULL
;
}
}
memset
(
&
inet
->
cork
.
fl
,
0
,
sizeof
(
inet
->
cork
.
fl
));
memset
(
&
inet
->
cork
.
fl
,
0
,
sizeof
(
inet
->
cork
.
fl
));
if
(
likely
(
idev
))
in6_dev_put
(
idev
);
return
err
;
return
err
;
error:
error:
goto
out
;
goto
out
;
...
@@ -1191,22 +1106,11 @@ void ip6_flush_pending_frames(struct sock *sk)
...
@@ -1191,22 +1106,11 @@ void ip6_flush_pending_frames(struct sock *sk)
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
struct
inet6_dev
*
idev
=
NULL
;
while
((
skb
=
__skb_dequeue_tail
(
&
sk
->
sk_write_queue
))
!=
NULL
)
{
while
((
skb
=
__skb_dequeue_tail
(
&
sk
->
sk_write_queue
))
!=
NULL
)
{
if
(
skb
->
dst
)
{
if
(
!
idev
||
skb
->
dst
->
dev
!=
idev
->
dev
)
{
if
(
idev
)
in6_dev_put
(
idev
);
idev
=
in6_dev_get
(
skb
->
dst
->
dev
);
}
}
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
}
}
if
(
idev
)
in6_dev_put
(
idev
);
inet
->
cork
.
flags
&=
~
IPCORK_OPT
;
inet
->
cork
.
flags
&=
~
IPCORK_OPT
;
...
...
net/ipv6/ipv6_sockglue.c
View file @
cf8cd3d1
...
@@ -56,7 +56,6 @@
...
@@ -56,7 +56,6 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
DEFINE_SNMP_STAT
(
struct
ipv6_mib
,
ipv6_statistics
);
DEFINE_SNMP_STAT
(
struct
ipv6_mib
,
ipv6_statistics
);
DEFINE_SNMP_STAT
(
struct
ip_stats
,
ipv6_stats
);
static
struct
packet_type
ipv6_packet_type
=
{
static
struct
packet_type
ipv6_packet_type
=
{
.
type
=
__constant_htons
(
ETH_P_IPV6
),
.
type
=
__constant_htons
(
ETH_P_IPV6
),
...
...
net/ipv6/mcast.c
View file @
cf8cd3d1
...
@@ -1318,8 +1318,6 @@ static void mld_sendpack(struct sk_buff *skb)
...
@@ -1318,8 +1318,6 @@ static void mld_sendpack(struct sk_buff *skb)
int
err
;
int
err
;
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
IPV6_ADD_STATS
(
idev
,
ipStatsOutOctets
,
skb
->
len
);
payload_len
=
skb
->
tail
-
(
unsigned
char
*
)
skb
->
nh
.
ipv6h
-
payload_len
=
skb
->
tail
-
(
unsigned
char
*
)
skb
->
nh
.
ipv6h
-
sizeof
(
struct
ipv6hdr
);
sizeof
(
struct
ipv6hdr
);
mldlen
=
skb
->
tail
-
skb
->
h
.
raw
;
mldlen
=
skb
->
tail
-
skb
->
h
.
raw
;
...
@@ -1332,13 +1330,10 @@ static void mld_sendpack(struct sk_buff *skb)
...
@@ -1332,13 +1330,10 @@ static void mld_sendpack(struct sk_buff *skb)
if
(
!
err
)
{
if
(
!
err
)
{
ICMP6_INC_STATS
(
idev
,
Icmp6OutMsgs
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutMsgs
);
IP6_INC_STATS
(
Ip6OutMcastPkts
);
IP6_INC_STATS
(
Ip6OutMcastPkts
);
IPV6_INC_STATS
(
idev
,
ipStatsOutMcastPkts
);
}
else
IPV6_ADD_STATS
(
idev
,
ipStatsOutMcastOctets
,
skb
->
len
);
}
else
{
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
}
if
(
likely
(
idev
!=
NULL
))
if
(
idev
)
in6_dev_put
(
idev
);
in6_dev_put
(
idev
);
}
}
...
@@ -1618,9 +1613,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
...
@@ -1618,9 +1613,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPV6_TLV_ROUTERALERT
,
2
,
0
,
0
,
IPV6_TLV_ROUTERALERT
,
2
,
0
,
0
,
IPV6_TLV_PADN
,
0
};
IPV6_TLV_PADN
,
0
};
idev
=
in6_dev_get
(
dev
);
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
snd_addr
=
addr
;
snd_addr
=
addr
;
if
(
type
==
ICMPV6_MGM_REDUCTION
)
{
if
(
type
==
ICMPV6_MGM_REDUCTION
)
{
snd_addr
=
&
all_routers
;
snd_addr
=
&
all_routers
;
...
@@ -1635,13 +1628,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
...
@@ -1635,13 +1628,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
if
(
skb
==
NULL
)
{
if
(
skb
==
NULL
)
{
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
if
(
idev
)
in6_dev_put
(
idev
);
return
;
return
;
}
}
IPV6_ADD_STATS
(
idev
,
ipStatsOutOctets
,
skb
->
len
);
skb_reserve
(
skb
,
LL_RESERVED_SPACE
(
dev
));
skb_reserve
(
skb
,
LL_RESERVED_SPACE
(
dev
));
if
(
dev
->
hard_header
)
{
if
(
dev
->
hard_header
)
{
unsigned
char
ha
[
MAX_ADDR_LEN
];
unsigned
char
ha
[
MAX_ADDR_LEN
];
...
@@ -1673,6 +1662,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
...
@@ -1673,6 +1662,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPPROTO_ICMPV6
,
IPPROTO_ICMPV6
,
csum_partial
((
__u8
*
)
hdr
,
len
,
0
));
csum_partial
((
__u8
*
)
hdr
,
len
,
0
));
idev
=
in6_dev_get
(
skb
->
dev
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
skb
->
dev
,
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
skb
->
dev
,
dev_queue_xmit
);
dev_queue_xmit
);
if
(
!
err
)
{
if
(
!
err
)
{
...
@@ -1682,22 +1673,16 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
...
@@ -1682,22 +1673,16 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
ICMP6_INC_STATS
(
idev
,
Icmp6OutGroupMembResponses
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutGroupMembResponses
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutMsgs
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutMsgs
);
IP6_INC_STATS
(
Ip6OutMcastPkts
);
IP6_INC_STATS
(
Ip6OutMcastPkts
);
IPV6_INC_STATS
(
idev
,
ipStatsOutMcastPkts
);
}
else
IPV6_ADD_STATS
(
idev
,
ipStatsOutMcastOctets
,
skb
->
len
);
}
else
{
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
}
if
(
likely
(
idev
!=
NULL
))
if
(
likely
(
idev
!=
NULL
))
in6_dev_put
(
idev
);
in6_dev_put
(
idev
);
return
;
return
;
out:
out:
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
if
(
likely
(
idev
!=
NULL
))
in6_dev_put
(
idev
);
}
}
static
int
ip6_mc_del1_src
(
struct
ifmcaddr6
*
pmc
,
int
sfmode
,
static
int
ip6_mc_del1_src
(
struct
ifmcaddr6
*
pmc
,
int
sfmode
,
...
...
net/ipv6/ndisc.c
View file @
cf8cd3d1
...
@@ -453,7 +453,6 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
...
@@ -453,7 +453,6 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
skb
->
dst
=
dst
;
skb
->
dst
=
dst
;
idev
=
in6_dev_get
(
dst
->
dev
);
idev
=
in6_dev_get
(
dst
->
dev
);
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
dst_output
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
dst_output
);
if
(
!
err
)
{
if
(
!
err
)
{
ICMP6_INC_STATS
(
idev
,
Icmp6OutNeighborAdvertisements
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutNeighborAdvertisements
);
...
@@ -538,7 +537,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
...
@@ -538,7 +537,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
skb
->
dst
=
dst
;
skb
->
dst
=
dst
;
idev
=
in6_dev_get
(
dst
->
dev
);
idev
=
in6_dev_get
(
dst
->
dev
);
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
dst_output
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
dst_output
);
if
(
!
err
)
{
if
(
!
err
)
{
ICMP6_INC_STATS
(
idev
,
Icmp6OutNeighborSolicits
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutNeighborSolicits
);
...
@@ -611,8 +609,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
...
@@ -611,8 +609,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
/* send it! */
/* send it! */
skb
->
dst
=
dst
;
skb
->
dst
=
dst
;
idev
=
in6_dev_get
(
dst
->
dev
);
idev
=
in6_dev_get
(
dst
->
dev
);
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
dst_output
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
dst
->
dev
,
dst_output
);
if
(
!
err
)
{
if
(
!
err
)
{
ICMP6_INC_STATS
(
idev
,
Icmp6OutRouterSolicits
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutRouterSolicits
);
...
@@ -1339,7 +1336,6 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
...
@@ -1339,7 +1336,6 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
buff
->
dst
=
dst
;
buff
->
dst
=
dst
;
idev
=
in6_dev_get
(
dst
->
dev
);
idev
=
in6_dev_get
(
dst
->
dev
);
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
buff
,
NULL
,
dst
->
dev
,
dst_output
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
buff
,
NULL
,
dst
->
dev
,
dst_output
);
if
(
!
err
)
{
if
(
!
err
)
{
ICMP6_INC_STATS
(
idev
,
Icmp6OutRedirects
);
ICMP6_INC_STATS
(
idev
,
Icmp6OutRedirects
);
...
...
net/ipv6/proc.c
View file @
cf8cd3d1
...
@@ -227,9 +227,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
...
@@ -227,9 +227,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
if
(
snmp6_mib_init
((
void
**
)
idev
->
stats
.
icmpv6
,
sizeof
(
struct
icmpv6_mib
),
if
(
snmp6_mib_init
((
void
**
)
idev
->
stats
.
icmpv6
,
sizeof
(
struct
icmpv6_mib
),
__alignof__
(
struct
icmpv6_mib
))
<
0
)
__alignof__
(
struct
icmpv6_mib
))
<
0
)
goto
err_icmp
;
goto
err_icmp
;
if
(
snmp6_mib_init
((
void
**
)
idev
->
stats
.
ipv6
,
sizeof
(
struct
ip_stats
),
__alignof__
(
struct
ip_stats
))
<
0
)
goto
err_ip
;
if
(
!
proc_net_devsnmp6
)
{
if
(
!
proc_net_devsnmp6
)
{
err
=
-
ENOENT
;
err
=
-
ENOENT
;
...
@@ -245,11 +242,8 @@ int snmp6_register_dev(struct inet6_dev *idev)
...
@@ -245,11 +242,8 @@ int snmp6_register_dev(struct inet6_dev *idev)
return
0
;
return
0
;
err_proc:
err_proc:
snmp6_mib_free
((
void
**
)
idev
->
stats
.
ipv6
);
err_ip:
snmp6_mib_free
((
void
**
)
idev
->
stats
.
icmpv6
);
snmp6_mib_free
((
void
**
)
idev
->
stats
.
icmpv6
);
err_icmp:
err_icmp:
return
err
;
return
err
;
}
}
...
@@ -262,7 +256,6 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
...
@@ -262,7 +256,6 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
remove_proc_entry
(
idev
->
stats
.
proc_dir_entry
->
name
,
remove_proc_entry
(
idev
->
stats
.
proc_dir_entry
->
name
,
proc_net_devsnmp6
);
proc_net_devsnmp6
);
snmp6_mib_free
((
void
**
)
idev
->
stats
.
icmpv6
);
snmp6_mib_free
((
void
**
)
idev
->
stats
.
icmpv6
);
snmp6_mib_free
((
void
**
)
idev
->
stats
.
ipv6
);
return
0
;
return
0
;
}
}
...
@@ -312,13 +305,9 @@ int snmp6_register_dev(struct inet6_dev *idev)
...
@@ -312,13 +305,9 @@ int snmp6_register_dev(struct inet6_dev *idev)
if
(
snmp6_mib_init
((
void
**
)
idev
->
stats
.
icmpv6
,
sizeof
(
struct
icmpv6_mib
),
if
(
snmp6_mib_init
((
void
**
)
idev
->
stats
.
icmpv6
,
sizeof
(
struct
icmpv6_mib
),
__alignof__
(
struct
icmpv6_mib
))
<
0
)
__alignof__
(
struct
icmpv6_mib
))
<
0
)
goto
err_icmp
;
goto
err_icmp
;
if
(
snmp6_mib_init
((
void
**
)
idev
->
stats
.
ipv6
,
sizeof
(
struct
ip_stats
),
__alignof__
(
struct
ip_stats
))
<
0
)
goto
err_ip
;
return
0
;
return
0
;
err_ip:
snmp6_mib_free
((
void
**
)
idev
->
stats
.
icmpv6
);
err_icmp:
err_icmp:
return
err
;
return
err
;
}
}
...
@@ -326,7 +315,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
...
@@ -326,7 +315,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
int
snmp6_unregister_dev
(
struct
inet6_dev
*
idev
)
int
snmp6_unregister_dev
(
struct
inet6_dev
*
idev
)
{
{
snmp6_mib_free
((
void
**
)
idev
->
stats
.
icmpv6
);
snmp6_mib_free
((
void
**
)
idev
->
stats
.
icmpv6
);
snmp6_mib_free
((
void
**
)
idev
->
stats
.
ipv6
);
return
0
;
return
0
;
}
}
...
...
net/ipv6/raw.c
View file @
cf8cd3d1
...
@@ -506,15 +506,11 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
...
@@ -506,15 +506,11 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
struct
ipv6hdr
*
iph
;
struct
ipv6hdr
*
iph
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
unsigned
int
hh_len
;
unsigned
int
hh_len
;
int
err
=
0
;
int
err
;
struct
inet6_dev
*
idev
=
NULL
;
/* hold reference for IP MIBs */
if
(
length
>
rt
->
u
.
dst
.
dev
->
mtu
)
{
if
(
length
>
rt
->
u
.
dst
.
dev
->
mtu
)
{
ipv6_local_error
(
sk
,
EMSGSIZE
,
fl
,
rt
->
u
.
dst
.
dev
->
mtu
);
ipv6_local_error
(
sk
,
EMSGSIZE
,
fl
,
rt
->
u
.
dst
.
dev
->
mtu
);
err
=
-
EMSGSIZE
;
return
-
EMSGSIZE
;
goto
out
;
}
}
if
(
flags
&
MSG_PROBE
)
if
(
flags
&
MSG_PROBE
)
goto
out
;
goto
out
;
...
@@ -530,9 +526,6 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
...
@@ -530,9 +526,6 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
skb
->
priority
=
sk
->
sk_priority
;
skb
->
priority
=
sk
->
sk_priority
;
skb
->
dst
=
dst_clone
(
&
rt
->
u
.
dst
);
skb
->
dst
=
dst_clone
(
&
rt
->
u
.
dst
);
if
(
skb
->
dst
)
idev
=
in6_dev_get
(
skb
->
dst
->
dev
);
skb
->
nh
.
ipv6h
=
iph
=
(
struct
ipv6hdr
*
)
skb_put
(
skb
,
length
);
skb
->
nh
.
ipv6h
=
iph
=
(
struct
ipv6hdr
*
)
skb_put
(
skb
,
length
);
skb
->
ip_summed
=
CHECKSUM_NONE
;
skb
->
ip_summed
=
CHECKSUM_NONE
;
...
@@ -542,27 +535,21 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
...
@@ -542,27 +535,21 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
if
(
err
)
if
(
err
)
goto
error_fault
;
goto
error_fault
;
IP6_INC_STATS
(
Ip6OutRequests
);
IP6_INC_STATS
(
Ip6OutRequests
);
IPV6_INC_STATS
(
idev
,
ipStatsOutRequests
);
IPV6_ADD_STATS
(
idev
,
ipStatsOutOctets
,
skb
->
len
);
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
rt
->
u
.
dst
.
dev
,
err
=
NF_HOOK
(
PF_INET6
,
NF_IP6_LOCAL_OUT
,
skb
,
NULL
,
rt
->
u
.
dst
.
dev
,
dst_output
);
dst_output
);
if
(
err
>
0
)
if
(
err
>
0
)
err
=
inet
->
recverr
?
net_xmit_errno
(
err
)
:
0
;
err
=
inet
->
recverr
?
net_xmit_errno
(
err
)
:
0
;
if
(
err
)
if
(
err
)
goto
error
;
goto
error
;
else
out:
goto
out
;
return
0
;
error_fault:
error_fault:
err
=
-
EFAULT
;
err
=
-
EFAULT
;
kfree_skb
(
skb
);
kfree_skb
(
skb
);
error:
error:
IP6_INC_STATS
(
Ip6OutDiscards
);
IP6_INC_STATS
(
Ip6OutDiscards
);
IPV6_INC_STATS
(
idev
,
ipStatsOutDiscards
);
out:
if
(
idev
)
in6_dev_put
(
idev
);
return
err
;
return
err
;
}
}
static
int
rawv6_sendmsg
(
struct
kiocb
*
iocb
,
struct
sock
*
sk
,
static
int
rawv6_sendmsg
(
struct
kiocb
*
iocb
,
struct
sock
*
sk
,
...
...
net/ipv6/reassembly.c
View file @
cf8cd3d1
...
@@ -264,7 +264,6 @@ static void ip6_evictor(void)
...
@@ -264,7 +264,6 @@ static void ip6_evictor(void)
{
{
struct
frag_queue
*
fq
;
struct
frag_queue
*
fq
;
struct
list_head
*
tmp
;
struct
list_head
*
tmp
;
struct
inet6_dev
*
idev
=
NULL
;
for
(;;)
{
for
(;;)
{
if
(
atomic_read
(
&
ip6_frag_mem
)
<=
sysctl_ip6frag_low_thresh
)
if
(
atomic_read
(
&
ip6_frag_mem
)
<=
sysctl_ip6frag_low_thresh
)
...
@@ -286,18 +285,12 @@ static void ip6_evictor(void)
...
@@ -286,18 +285,12 @@ static void ip6_evictor(void)
fq_put
(
fq
);
fq_put
(
fq
);
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
/* idev might be pointed to NULL */
if
(
fq
->
fragments
)
idev
=
__in6_dev_get
(
fq
->
fragments
->
dev
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmFails
);
}
}
}
}
static
void
ip6_frag_expire
(
unsigned
long
data
)
static
void
ip6_frag_expire
(
unsigned
long
data
)
{
{
struct
frag_queue
*
fq
=
(
struct
frag_queue
*
)
data
;
struct
frag_queue
*
fq
=
(
struct
frag_queue
*
)
data
;
struct
net_device
*
dev
;
struct
inet6_dev
*
idev
=
NULL
;
spin_lock
(
&
fq
->
lock
);
spin_lock
(
&
fq
->
lock
);
...
@@ -308,14 +301,10 @@ static void ip6_frag_expire(unsigned long data)
...
@@ -308,14 +301,10 @@ static void ip6_frag_expire(unsigned long data)
IP6_INC_STATS_BH
(
Ip6ReasmTimeout
);
IP6_INC_STATS_BH
(
Ip6ReasmTimeout
);
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
dev
=
dev_get_by_index
(
fq
->
iif
);
if
(
dev
)
idev
=
__in6_dev_get
(
dev
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInDiscards
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmFails
);
/* Send error only if the first segment arrived. */
/* Send error only if the first segment arrived. */
if
(
fq
->
last_in
&
FIRST_IN
&&
fq
->
fragments
)
{
if
(
fq
->
last_in
&
FIRST_IN
&&
fq
->
fragments
)
{
struct
net_device
*
dev
=
dev_get_by_index
(
fq
->
iif
);
/*
/*
But use as source device on which LAST ARRIVED
But use as source device on which LAST ARRIVED
...
@@ -326,10 +315,9 @@ static void ip6_frag_expire(unsigned long data)
...
@@ -326,10 +315,9 @@ static void ip6_frag_expire(unsigned long data)
fq
->
fragments
->
dev
=
dev
;
fq
->
fragments
->
dev
=
dev
;
icmpv6_send
(
fq
->
fragments
,
ICMPV6_TIME_EXCEED
,
ICMPV6_EXC_FRAGTIME
,
0
,
icmpv6_send
(
fq
->
fragments
,
ICMPV6_TIME_EXCEED
,
ICMPV6_EXC_FRAGTIME
,
0
,
dev
);
dev
);
dev_put
(
dev
);
}
}
}
}
if
(
dev
)
dev_put
(
dev
);
out:
out:
spin_unlock
(
&
fq
->
lock
);
spin_unlock
(
&
fq
->
lock
);
fq_put
(
fq
);
fq_put
(
fq
);
...
@@ -379,7 +367,6 @@ static struct frag_queue *
...
@@ -379,7 +367,6 @@ static struct frag_queue *
ip6_frag_create
(
unsigned
int
hash
,
u32
id
,
struct
in6_addr
*
src
,
struct
in6_addr
*
dst
)
ip6_frag_create
(
unsigned
int
hash
,
u32
id
,
struct
in6_addr
*
src
,
struct
in6_addr
*
dst
)
{
{
struct
frag_queue
*
fq
;
struct
frag_queue
*
fq
;
struct
inet6_dev
*
idev
=
NULL
;
if
((
fq
=
frag_alloc_queue
())
==
NULL
)
if
((
fq
=
frag_alloc_queue
())
==
NULL
)
goto
oom
;
goto
oom
;
...
@@ -400,7 +387,6 @@ ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr
...
@@ -400,7 +387,6 @@ ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr
oom:
oom:
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmFails
);
return
NULL
;
return
NULL
;
}
}
...
@@ -431,10 +417,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
...
@@ -431,10 +417,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
{
{
struct
sk_buff
*
prev
,
*
next
;
struct
sk_buff
*
prev
,
*
next
;
int
offset
,
end
;
int
offset
,
end
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
skb
->
dev
)
idev
=
__in6_dev_get
(
skb
->
dev
);
if
(
fq
->
last_in
&
COMPLETE
)
if
(
fq
->
last_in
&
COMPLETE
)
goto
err
;
goto
err
;
...
@@ -444,7 +427,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
...
@@ -444,7 +427,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
if
((
unsigned
int
)
end
>
IPV6_MAXPLEN
)
{
if
((
unsigned
int
)
end
>
IPV6_MAXPLEN
)
{
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
u8
*
)
&
fhdr
->
frag_off
-
skb
->
nh
.
raw
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
(
u8
*
)
&
fhdr
->
frag_off
-
skb
->
nh
.
raw
);
return
;
return
;
}
}
...
@@ -472,7 +454,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
...
@@ -472,7 +454,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
* this case. -DaveM
* this case. -DaveM
*/
*/
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IP6_INC_STATS_BH
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
offsetof
(
struct
ipv6hdr
,
payload_len
));
offsetof
(
struct
ipv6hdr
,
payload_len
));
return
;
return
;
...
@@ -592,7 +573,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
...
@@ -592,7 +573,6 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
err:
err:
IP6_INC_STATS
(
Ip6ReasmFails
);
IP6_INC_STATS
(
Ip6ReasmFails
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmFails
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
}
}
...
@@ -612,10 +592,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
...
@@ -612,10 +592,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
struct
sk_buff
*
fp
,
*
head
=
fq
->
fragments
;
struct
sk_buff
*
fp
,
*
head
=
fq
->
fragments
;
int
payload_len
;
int
payload_len
;
unsigned
int
nhoff
;
unsigned
int
nhoff
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
dev
)
idev
=
__in6_dev_get
(
dev
);
fq_kill
(
fq
);
fq_kill
(
fq
);
BUG_TRAP
(
head
!=
NULL
);
BUG_TRAP
(
head
!=
NULL
);
...
@@ -690,7 +667,6 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
...
@@ -690,7 +667,6 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
head
->
csum
=
csum_partial
(
head
->
nh
.
raw
,
head
->
h
.
raw
-
head
->
nh
.
raw
,
head
->
csum
);
head
->
csum
=
csum_partial
(
head
->
nh
.
raw
,
head
->
h
.
raw
-
head
->
nh
.
raw
,
head
->
csum
);
IP6_INC_STATS_BH
(
Ip6ReasmOKs
);
IP6_INC_STATS_BH
(
Ip6ReasmOKs
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmOKs
);
fq
->
fragments
=
NULL
;
fq
->
fragments
=
NULL
;
*
nhoffp
=
nhoff
;
*
nhoffp
=
nhoff
;
return
1
;
return
1
;
...
@@ -704,7 +680,6 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
...
@@ -704,7 +680,6 @@ 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
"
);
printk
(
KERN_DEBUG
"ip6_frag_reasm: no memory for reassembly
\n
"
);
out_fail:
out_fail:
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmFails
);
return
-
1
;
return
-
1
;
}
}
...
@@ -715,25 +690,19 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -715,25 +690,19 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
struct
frag_hdr
*
fhdr
;
struct
frag_hdr
*
fhdr
;
struct
frag_queue
*
fq
;
struct
frag_queue
*
fq
;
struct
ipv6hdr
*
hdr
;
struct
ipv6hdr
*
hdr
;
struct
inet6_dev
*
idev
=
NULL
;
if
(
dev
)
idev
=
__in6_dev_get
(
dev
);
hdr
=
skb
->
nh
.
ipv6h
;
hdr
=
skb
->
nh
.
ipv6h
;
IP6_INC_STATS_BH
(
Ip6ReasmReqds
);
IP6_INC_STATS_BH
(
Ip6ReasmReqds
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmReqds
);
/* Jumbo payload inhibits frag. header */
/* Jumbo payload inhibits frag. header */
if
(
hdr
->
payload_len
==
0
)
{
if
(
hdr
->
payload_len
==
0
)
{
IP6_INC_STATS
(
Ip6InHdrErrors
);
IP6_INC_STATS
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
);
return
-
1
;
return
-
1
;
}
}
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
sizeof
(
struct
frag_hdr
)))
{
if
(
!
pskb_may_pull
(
skb
,
(
skb
->
h
.
raw
-
skb
->
data
)
+
sizeof
(
struct
frag_hdr
)))
{
IP6_INC_STATS
(
Ip6InHdrErrors
);
IP6_INC_STATS
(
Ip6InHdrErrors
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsInHdrErrors
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
);
icmpv6_param_prob
(
skb
,
ICMPV6_HDR_FIELD
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
);
return
-
1
;
return
-
1
;
}
}
...
@@ -745,7 +714,6 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -745,7 +714,6 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
/* It is not a fragmented frame */
/* It is not a fragmented frame */
skb
->
h
.
raw
+=
sizeof
(
struct
frag_hdr
);
skb
->
h
.
raw
+=
sizeof
(
struct
frag_hdr
);
IP6_INC_STATS_BH
(
Ip6ReasmOKs
);
IP6_INC_STATS_BH
(
Ip6ReasmOKs
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmOKs
);
*
nhoffp
=
(
u8
*
)
fhdr
-
skb
->
nh
.
raw
;
*
nhoffp
=
(
u8
*
)
fhdr
-
skb
->
nh
.
raw
;
return
1
;
return
1
;
...
@@ -771,7 +739,6 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
...
@@ -771,7 +739,6 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
}
}
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IP6_INC_STATS_BH
(
Ip6ReasmFails
);
IPV6_INC_STATS_BH
(
idev
,
ipStatsReasmFails
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
-
1
;
return
-
1
;
}
}
...
...
net/ipv6/route.c
View file @
cf8cd3d1
...
@@ -85,8 +85,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
...
@@ -85,8 +85,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static
struct
dst_entry
*
ip6_negative_advice
(
struct
dst_entry
*
);
static
struct
dst_entry
*
ip6_negative_advice
(
struct
dst_entry
*
);
static
int
ip6_dst_gc
(
void
);
static
int
ip6_dst_gc
(
void
);
static
int
ip6_pkt_indiscard
(
struct
sk_buff
*
skb
);
static
int
ip6_pkt_discard
(
struct
sk_buff
*
skb
);
static
int
ip6_pkt_outdiscard
(
struct
sk_buff
*
skb
);
static
void
ip6_link_failure
(
struct
sk_buff
*
skb
);
static
void
ip6_link_failure
(
struct
sk_buff
*
skb
);
static
void
ip6_rt_update_pmtu
(
struct
dst_entry
*
dst
,
u32
mtu
);
static
void
ip6_rt_update_pmtu
(
struct
dst_entry
*
dst
,
u32
mtu
);
...
@@ -111,8 +110,8 @@ struct rt6_info ip6_null_entry = {
...
@@ -111,8 +110,8 @@ struct rt6_info ip6_null_entry = {
.
obsolete
=
-
1
,
.
obsolete
=
-
1
,
.
error
=
-
ENETUNREACH
,
.
error
=
-
ENETUNREACH
,
.
metrics
=
{
[
RTAX_HOPLIMIT
-
1
]
=
255
,
},
.
metrics
=
{
[
RTAX_HOPLIMIT
-
1
]
=
255
,
},
.
input
=
ip6_pkt_
in
discard
,
.
input
=
ip6_pkt_discard
,
.
output
=
ip6_pkt_
out
discard
,
.
output
=
ip6_pkt_discard
,
.
ops
=
&
ip6_dst_ops
,
.
ops
=
&
ip6_dst_ops
,
.
path
=
(
struct
dst_entry
*
)
&
ip6_null_entry
,
.
path
=
(
struct
dst_entry
*
)
&
ip6_null_entry
,
}
}
...
@@ -770,8 +769,8 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
...
@@ -770,8 +769,8 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
dev_put
(
dev
);
dev_put
(
dev
);
dev
=
&
loopback_dev
;
dev
=
&
loopback_dev
;
dev_hold
(
dev
);
dev_hold
(
dev
);
rt
->
u
.
dst
.
output
=
ip6_pkt_
out
discard
;
rt
->
u
.
dst
.
output
=
ip6_pkt_discard
;
rt
->
u
.
dst
.
input
=
ip6_pkt_
in
discard
;
rt
->
u
.
dst
.
input
=
ip6_pkt_discard
;
rt
->
u
.
dst
.
error
=
-
ENETUNREACH
;
rt
->
u
.
dst
.
error
=
-
ENETUNREACH
;
rt
->
rt6i_flags
=
RTF_REJECT
|
RTF_NONEXTHOP
;
rt
->
rt6i_flags
=
RTF_REJECT
|
RTF_NONEXTHOP
;
goto
install_route
;
goto
install_route
;
...
@@ -1258,30 +1257,9 @@ int ipv6_route_ioctl(unsigned int cmd, void *arg)
...
@@ -1258,30 +1257,9 @@ int ipv6_route_ioctl(unsigned int cmd, void *arg)
* Drop the packet on the floor
* Drop the packet on the floor
*/
*/
static
int
ip6_pkt_in
discard
(
struct
sk_buff
*
skb
)
int
ip6_pkt_
discard
(
struct
sk_buff
*
skb
)
{
{
struct
inet6_dev
*
idev
=
NULL
;
if
(
skb
->
dev
)
idev
=
__in6_dev_get
(
skb
->
dev
);
IP6_INC_STATS
(
Ip6InNoRoutes
);
IPV6_INC_STATS
(
idev
,
ipStatsInNoRoutes
);
icmpv6_send
(
skb
,
ICMPV6_DEST_UNREACH
,
ICMPV6_NOROUTE
,
0
,
skb
->
dev
);
kfree_skb
(
skb
);
return
0
;
}
static
int
ip6_pkt_outdiscard
(
struct
sk_buff
*
skb
)
{
struct
inet6_dev
*
idev
=
NULL
;
if
(
skb
->
dev
)
idev
=
__in6_dev_get
(
skb
->
dev
);
IP6_INC_STATS
(
Ip6OutNoRoutes
);
IP6_INC_STATS
(
Ip6OutNoRoutes
);
IPV6_INC_STATS
(
idev
,
ipStatsOutNoRoutes
);
icmpv6_send
(
skb
,
ICMPV6_DEST_UNREACH
,
ICMPV6_NOROUTE
,
0
,
skb
->
dev
);
icmpv6_send
(
skb
,
ICMPV6_DEST_UNREACH
,
ICMPV6_NOROUTE
,
0
,
skb
->
dev
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
0
;
return
0
;
...
...
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