Add stat counter for ipv6 atomic fragments
Add a stat counter to track ipv6 atomic fragments. Atomic fragments can be generated in response to invalid path MTU values, but are also a potential attack vector and considered harmful (see RFC6946 and RFC8021). While here add tracking of the atomic fragment counter to netstat and systat. Reviewed by: tuexen, jtl, bz Approved by: jtl (mentor), bz (mentor) Event: Aberdeen hackathon 2019 Differential Revision: https://reviews.freebsd.org/D17511
This commit is contained in:
parent
48ecceba1e
commit
2946a9415c
@ -277,12 +277,12 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
offset += sizeof(struct ip6_frag);
|
offset += sizeof(struct ip6_frag);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RFC 6946: Handle "atomic" fragments (offset and m bit set to 0)
|
* Handle "atomic" fragments (offset and m bit set to 0) upfront,
|
||||||
* upfront, unrelated to any reassembly. Just skip the fragment header.
|
* unrelated to any reassembly (see RFC 6946 and section 4.5 of RFC
|
||||||
|
* 8200). Just skip the fragment header.
|
||||||
*/
|
*/
|
||||||
if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
|
if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
|
||||||
/* XXX-BZ we want dedicated counters for this. */
|
IP6STAT_INC(ip6s_atomicfrags);
|
||||||
IP6STAT_INC(ip6s_reassembled);
|
|
||||||
in6_ifstat_inc(dstifp, ifs6_reass_ok);
|
in6_ifstat_inc(dstifp, ifs6_reass_ok);
|
||||||
*offp = offset;
|
*offp = offset;
|
||||||
m->m_flags |= M_FRAGMENTED;
|
m->m_flags |= M_FRAGMENTED;
|
||||||
|
@ -208,6 +208,7 @@ struct ip6stat {
|
|||||||
uint64_t ip6s_localout; /* total ip packets generated here */
|
uint64_t ip6s_localout; /* total ip packets generated here */
|
||||||
uint64_t ip6s_odropped; /* lost packets due to nobufs, etc. */
|
uint64_t ip6s_odropped; /* lost packets due to nobufs, etc. */
|
||||||
uint64_t ip6s_reassembled; /* total packets reassembled ok */
|
uint64_t ip6s_reassembled; /* total packets reassembled ok */
|
||||||
|
uint64_t ip6s_atomicfrags; /* atomic fragments */
|
||||||
uint64_t ip6s_fragmented; /* datagrams successfully fragmented */
|
uint64_t ip6s_fragmented; /* datagrams successfully fragmented */
|
||||||
uint64_t ip6s_ofragments; /* output fragments created */
|
uint64_t ip6s_ofragments; /* output fragments created */
|
||||||
uint64_t ip6s_cantfrag; /* don't fragment flag was set, etc. */
|
uint64_t ip6s_cantfrag; /* don't fragment flag was set, etc. */
|
||||||
|
@ -391,6 +391,8 @@ ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
|
|||||||
"{N:/fragment%s dropped after timeout}\n");
|
"{N:/fragment%s dropped after timeout}\n");
|
||||||
p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
|
p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
|
||||||
"{N:/fragment%s that exceeded limit}\n");
|
"{N:/fragment%s that exceeded limit}\n");
|
||||||
|
p(ip6s_atomicfrags, "\t{:atomic-fragments/%ju} "
|
||||||
|
"{N:/atomic fragment%s}\n");
|
||||||
p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
|
p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
|
||||||
"{N:/packet%s reassembled ok}\n");
|
"{N:/packet%s reassembled ok}\n");
|
||||||
p(ip6s_delivered, "\t{:received-local-packets/%ju} "
|
p(ip6s_delivered, "\t{:received-local-packets/%ju} "
|
||||||
|
@ -121,16 +121,16 @@ labelip6(void)
|
|||||||
L(6, "- fragments dropped"); R(6, "destinations unreachable");
|
L(6, "- fragments dropped"); R(6, "destinations unreachable");
|
||||||
L(7, "- fragments timed out"); R(7, "packets output via raw IP");
|
L(7, "- fragments timed out"); R(7, "packets output via raw IP");
|
||||||
L(8, "- fragments overflown");
|
L(8, "- fragments overflown");
|
||||||
L(9, "- packets reassembled ok"); R(9, "Input next-header histogram");
|
L(9, "- atomic fragments"); R(9, "Input next-header histogram");
|
||||||
L(10, "packets forwarded"); R(10, " - destination options");
|
L(10, "- packets reassembled ok"); R(10, " - destination options");
|
||||||
L(11, "- unreachable dests"); R(11, " - hop-by-hop options");
|
L(11, "packets forwarded"); R(11, " - hop-by-hop options");
|
||||||
L(12, "- redirects generated"); R(12, " - IPv4");
|
L(12, "- unreachable dests"); R(12, " - IPv4");
|
||||||
L(13, "option errors"); R(13, " - TCP");
|
L(13, "- redirects generated"); R(13, " - TCP");
|
||||||
L(14, "unwanted multicasts"); R(14, " - UDP");
|
L(14, "option errors"); R(14, " - UDP");
|
||||||
L(15, "delivered to upper layer"); R(15, " - IPv6");
|
L(15, "unwanted multicasts"); R(15, " - IPv6");
|
||||||
L(16, "bad scope packets"); R(16, " - routing header");
|
L(16, "delivered to upper layer"); R(16, " - routing header");
|
||||||
L(17, "address selection failed"); R(17, " - fragmentation header");
|
L(17, "bad scope packets"); R(17, " - fragmentation header");
|
||||||
R(18, " - ICMP6");
|
L(18, "address selection failed");R(18, " - ICMP6");
|
||||||
R(19, " - none");
|
R(19, " - none");
|
||||||
#undef L
|
#undef L
|
||||||
#undef R
|
#undef R
|
||||||
@ -165,6 +165,7 @@ domode(struct ip6stat *ret)
|
|||||||
DO(ip6s_fragdropped);
|
DO(ip6s_fragdropped);
|
||||||
DO(ip6s_fragtimeout);
|
DO(ip6s_fragtimeout);
|
||||||
DO(ip6s_fragoverflow);
|
DO(ip6s_fragoverflow);
|
||||||
|
DO(ip6s_atomicfrags);
|
||||||
DO(ip6s_forward);
|
DO(ip6s_forward);
|
||||||
DO(ip6s_cantforward);
|
DO(ip6s_cantforward);
|
||||||
DO(ip6s_redirectsent);
|
DO(ip6s_redirectsent);
|
||||||
@ -214,22 +215,23 @@ showip6(void)
|
|||||||
DO(ip6s_fragtimeout, 7, 0);
|
DO(ip6s_fragtimeout, 7, 0);
|
||||||
DO(ip6s_rawout, 7, 35);
|
DO(ip6s_rawout, 7, 35);
|
||||||
DO(ip6s_fragoverflow, 8, 0);
|
DO(ip6s_fragoverflow, 8, 0);
|
||||||
DO(ip6s_reassembled, 9, 0);
|
DO(ip6s_atomicfrags, 9, 0);
|
||||||
DO(ip6s_forward, 10, 0);
|
DO(ip6s_reassembled, 10, 0);
|
||||||
|
DO(ip6s_forward, 11, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_DSTOPTS], 10, 35);
|
DO(ip6s_nxthist[IPPROTO_DSTOPTS], 10, 35);
|
||||||
DO(ip6s_cantforward, 11, 0);
|
DO(ip6s_cantforward, 12, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_HOPOPTS], 11, 35);
|
DO(ip6s_nxthist[IPPROTO_HOPOPTS], 11, 35);
|
||||||
DO(ip6s_redirectsent, 12, 0);
|
DO(ip6s_redirectsent, 13, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_IPV4], 12, 35);
|
DO(ip6s_nxthist[IPPROTO_IPV4], 12, 35);
|
||||||
DO(ip6s_badoptions, 13, 0);
|
DO(ip6s_badoptions, 14, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_TCP], 13, 35);
|
DO(ip6s_nxthist[IPPROTO_TCP], 13, 35);
|
||||||
DO(ip6s_notmember, 14, 0);
|
DO(ip6s_notmember, 15, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_UDP], 14, 35);
|
DO(ip6s_nxthist[IPPROTO_UDP], 14, 35);
|
||||||
DO(ip6s_delivered, 15, 0);
|
DO(ip6s_delivered, 16, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_IPV6], 15, 35);
|
DO(ip6s_nxthist[IPPROTO_IPV6], 15, 35);
|
||||||
DO(ip6s_badscope, 16, 0);
|
DO(ip6s_badscope, 17, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_ROUTING], 16, 35);
|
DO(ip6s_nxthist[IPPROTO_ROUTING], 16, 35);
|
||||||
DO(ip6s_sources_none, 17, 0);
|
DO(ip6s_sources_none, 18, 0);
|
||||||
DO(ip6s_nxthist[IPPROTO_FRAGMENT], 17, 35);
|
DO(ip6s_nxthist[IPPROTO_FRAGMENT], 17, 35);
|
||||||
DO(ip6s_nxthist[IPPROTO_ICMPV6], 18, 35);
|
DO(ip6s_nxthist[IPPROTO_ICMPV6], 18, 35);
|
||||||
DO(ip6s_nxthist[IPPROTO_NONE], 19, 35);
|
DO(ip6s_nxthist[IPPROTO_NONE], 19, 35);
|
||||||
|
Loading…
Reference in New Issue
Block a user