FreeBSD kernel IPv4 code
ip_reass.c File Reference
#include <sys/cdefs.h>
#include "opt_rss.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/hash.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/rss_config.h>
#include <net/netisr.h>
#include <net/vnet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/in_rss.h>
Include dependency graph for ip_reass.c:

Go to the source code of this file.

Data Structures

struct  ipqbucket
 

Macros

#define IPREASS_NHASH_LOG2   10
 
#define IPREASS_NHASH   (1 << IPREASS_NHASH_LOG2)
 
#define IPREASS_HMASK   (IPREASS_NHASH - 1)
 
#define V_ipq   VNET(ipq)
 
#define V_ipq_hashseed   VNET(ipq_hashseed)
 
#define IPQ_LOCK(i)   mtx_lock(&V_ipq[i].lock)
 
#define IPQ_TRYLOCK(i)   mtx_trylock(&V_ipq[i].lock)
 
#define IPQ_UNLOCK(i)   mtx_unlock(&V_ipq[i].lock)
 
#define IPQ_LOCK_ASSERT(i)   mtx_assert(&V_ipq[i].lock, MA_OWNED)
 
#define V_ipreass_maxbucketsize   VNET(ipreass_maxbucketsize)
 
#define IP_MAXFRAGS   (nmbclusters / 32)
 
#define IP_MAXFRAGPACKETS   (imin(IP_MAXFRAGS, IPREASS_NHASH * 50))
 
#define V_ipq_zone   VNET(ipq_zone)
 
#define V_noreass   VNET(noreass)
 
#define V_maxfragsperpacket   VNET(maxfragsperpacket)
 
#define M_IP_FRAG   M_PROTO9
 
#define GETIP(m)   ((struct ip*)((m)->m_pkthdr.PH_loc.ptr))
 

Functions

 __FBSDID ("$FreeBSD$")
 
 SYSCTL_DECL (_net_inet_ip)
 
 VNET_DEFINE_STATIC (struct ipqbucket, ipq[IPREASS_NHASH])
 
 VNET_DEFINE_STATIC (uint32_t, ipq_hashseed)
 
 VNET_DEFINE_STATIC (int, ipreass_maxbucketsize)
 
void ipreass_init (void)
 
void ipreass_drain (void)
 
void ipreass_slowtimo (void)
 
static int sysctl_maxfragpackets (SYSCTL_HANDLER_ARGS)
 
static int sysctl_maxfragbucketsize (SYSCTL_HANDLER_ARGS)
 
static void ipreass_zone_change (void *)
 
static void ipreass_drain_tomax (void)
 
static void ipq_free (struct ipqbucket *, struct ipq *)
 
static struct ipqipq_reuse (int)
 
static void ipq_timeout (struct ipqbucket *bucket, struct ipq *fp)
 
static void ipq_drop (struct ipqbucket *bucket, struct ipq *fp)
 
 SYSCTL_INT (_net_inet_ip, OID_AUTO, maxfrags, CTLFLAG_RW, &maxfrags, 0, "Maximum number of IPv4 fragments allowed across all reassembly queues")
 
 SYSCTL_UINT (_net_inet_ip, OID_AUTO, curfrags, CTLFLAG_RD, &nfrags, 0, "Current number of IPv4 fragments across all reassembly queues")
 
 VNET_DEFINE_STATIC (uma_zone_t, ipq_zone)
 
 SYSCTL_PROC (_net_inet_ip, OID_AUTO, maxfragpackets, CTLFLAG_VNET|CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_NEEDGIANT, NULL, 0, sysctl_maxfragpackets, "I", "Maximum number of IPv4 fragment reassembly queue entries")
 
 SYSCTL_UMA_CUR (_net_inet_ip, OID_AUTO, fragpackets, CTLFLAG_VNET, &VNET_NAME(ipq_zone), "Current number of IPv4 fragment reassembly queue entries")
 
 VNET_DEFINE_STATIC (int, noreass)
 
 VNET_DEFINE_STATIC (int, maxfragsperpacket)
 
 SYSCTL_INT (_net_inet_ip, OID_AUTO, maxfragsperpacket, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(maxfragsperpacket), 0, "Maximum number of IPv4 fragments allowed per packet")
 
 SYSCTL_PROC (_net_inet_ip, OID_AUTO, maxfragbucketsize, CTLFLAG_VNET|CTLTYPE_INT|CTLFLAG_MPSAFE|CTLFLAG_RW, NULL, 0, sysctl_maxfragbucketsize, "I", "Maximum number of IPv4 fragment reassembly queue entries per bucket")
 
struct mbuf * ip_reass (struct mbuf *m)
 
static void ipreass_cleanup (void *arg __unused, struct ifnet *ifp)
 
 EVENTHANDLER_DEFINE (ifnet_departure_event, ipreass_cleanup, NULL, 0)
 

Variables

static int maxfrags
 
static u_int __exclusive_cache_line nfrags
 

Macro Definition Documentation

◆ GETIP

#define GETIP (   m)    ((struct ip*)((m)->m_pkthdr.PH_loc.ptr))

◆ IP_MAXFRAGPACKETS

#define IP_MAXFRAGPACKETS   (imin(IP_MAXFRAGS, IPREASS_NHASH * 50))

Definition at line 137 of file ip_reass.c.

◆ IP_MAXFRAGS

#define IP_MAXFRAGS   (nmbclusters / 32)

Definition at line 136 of file ip_reass.c.

◆ IPQ_LOCK

#define IPQ_LOCK (   i)    mtx_lock(&V_ipq[i].lock)

Definition at line 86 of file ip_reass.c.

◆ IPQ_LOCK_ASSERT

#define IPQ_LOCK_ASSERT (   i)    mtx_assert(&V_ipq[i].lock, MA_OWNED)

Definition at line 89 of file ip_reass.c.

◆ IPQ_TRYLOCK

#define IPQ_TRYLOCK (   i)    mtx_trylock(&V_ipq[i].lock)

Definition at line 87 of file ip_reass.c.

◆ IPQ_UNLOCK

#define IPQ_UNLOCK (   i)    mtx_unlock(&V_ipq[i].lock)

Definition at line 88 of file ip_reass.c.

◆ IPREASS_HMASK

#define IPREASS_HMASK   (IPREASS_NHASH - 1)

Definition at line 73 of file ip_reass.c.

◆ IPREASS_NHASH

#define IPREASS_NHASH   (1 << IPREASS_NHASH_LOG2)

Definition at line 72 of file ip_reass.c.

◆ IPREASS_NHASH_LOG2

#define IPREASS_NHASH_LOG2   10

Definition at line 71 of file ip_reass.c.

◆ M_IP_FRAG

#define M_IP_FRAG   M_PROTO9

Definition at line 181 of file ip_reass.c.

◆ V_ipq

#define V_ipq   VNET(ipq)

Definition at line 82 of file ip_reass.c.

◆ V_ipq_hashseed

#define V_ipq_hashseed   VNET(ipq_hashseed)

Definition at line 84 of file ip_reass.c.

◆ V_ipq_zone

#define V_ipq_zone   VNET(ipq_zone)

Definition at line 149 of file ip_reass.c.

◆ V_ipreass_maxbucketsize

#define V_ipreass_maxbucketsize   VNET(ipreass_maxbucketsize)

Definition at line 92 of file ip_reass.c.

◆ V_maxfragsperpacket

#define V_maxfragsperpacket   VNET(maxfragsperpacket)

Definition at line 162 of file ip_reass.c.

◆ V_noreass

#define V_noreass   VNET(noreass)

Definition at line 159 of file ip_reass.c.

Function Documentation

◆ __FBSDID()

__FBSDID ( "$FreeBSD$"  )

◆ EVENTHANDLER_DEFINE()

EVENTHANDLER_DEFINE ( ifnet_departure_event  ,
ipreass_cleanup  ,
NULL  ,
 
)

◆ ip_reass()

◆ ipq_drop()

static void ipq_drop ( struct ipqbucket bucket,
struct ipq fp 
)
inlinestatic

Definition at line 116 of file ip_reass.c.

References bucket, ipq_free(), ipq::ipq_nfrags, and IPSTAT_ADD.

Referenced by ip_reass(), and ipreass_drain().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipq_free()

static void ipq_free ( struct ipqbucket bucket,
struct ipq fp 
)
static

Definition at line 829 of file ip_reass.c.

References bucket, ipq::ipq_frags, ipq::ipq_nfrags, nfrags, and V_ipq_zone.

Referenced by ipq_drop(), and ipq_timeout().

Here is the caller graph for this function:

◆ ipq_reuse()

static struct ipq * ipq_reuse ( int  start)
static

Definition at line 790 of file ip_reass.c.

References bucket, ipq::ipq_frags, IPQ_LOCK_ASSERT, ipq::ipq_nfrags, IPQ_TRYLOCK, IPQ_UNLOCK, IPREASS_NHASH, IPSTAT_ADD, nfrags, and V_ipq.

Referenced by ip_reass().

Here is the caller graph for this function:

◆ ipq_timeout()

static void ipq_timeout ( struct ipqbucket bucket,
struct ipq fp 
)
inlinestatic

Definition at line 108 of file ip_reass.c.

References bucket, ipq_free(), ipq::ipq_nfrags, and IPSTAT_ADD.

Referenced by ipreass_drain_tomax(), and ipreass_slowtimo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipreass_cleanup()

static void ipreass_cleanup ( void *arg  __unused,
struct ifnet *  ifp 
)
static

Definition at line 633 of file ip_reass.c.

References ipq::ipq_frags, IPQ_LOCK, IPQ_UNLOCK, IPREASS_NHASH, V_ipq, and V_ipq_zone.

◆ ipreass_drain()

void ipreass_drain ( void  )

Definition at line 614 of file ip_reass.c.

References count, ipq_drop(), IPQ_LOCK, IPQ_UNLOCK, IPREASS_NHASH, and V_ipq.

Referenced by ip_drain(), and sysctl_maxfragpackets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipreass_drain_tomax()

static void ipreass_drain_tomax ( void  )
static

Definition at line 690 of file ip_reass.c.

References count, IPQ_LOCK, ipq_timeout(), IPQ_UNLOCK, IPREASS_NHASH, V_ipq, V_ipq_zone, and V_ipreass_maxbucketsize.

Referenced by ipreass_zone_change(), sysctl_maxfragbucketsize(), and sysctl_maxfragpackets().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipreass_init()

void ipreass_init ( void  )

Definition at line 563 of file ip_reass.c.

References IP_MAXFRAGPACKETS, IP_MAXFRAGS, IPREASS_NHASH, ipreass_zone_change(), maxfrags, V_ipq, V_ipq_hashseed, V_ipq_zone, V_ipreass_maxbucketsize, and V_maxfragsperpacket.

Referenced by ip_vnet_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipreass_slowtimo()

void ipreass_slowtimo ( void  )

Definition at line 592 of file ip_reass.c.

References IPQ_LOCK, ipq_timeout(), ipq::ipq_ttl, IPQ_UNLOCK, IPREASS_NHASH, nfrags, and V_ipq.

Referenced by ip_slowtimo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipreass_zone_change()

static void ipreass_zone_change ( void *  tag)
static

Definition at line 727 of file ip_reass.c.

References IP_MAXFRAGPACKETS, IP_MAXFRAGS, ipreass_drain_tomax(), IPREASS_NHASH, maxfrags, V_ipq_zone, and V_ipreass_maxbucketsize.

Referenced by ipreass_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SYSCTL_DECL()

SYSCTL_DECL ( _net_inet_ip  )

◆ SYSCTL_INT() [1/2]

SYSCTL_INT ( _net_inet_ip  ,
OID_AUTO  ,
maxfrags  ,
CTLFLAG_RW  ,
maxfrags,
,
"Maximum number of IPv4 fragments allowed across all reassembly queues"   
)

◆ SYSCTL_INT() [2/2]

SYSCTL_INT ( _net_inet_ip  ,
OID_AUTO  ,
maxfragsperpacket  ,
CTLFLAG_VNET|  CTLFLAG_RW,
VNET_NAMEmaxfragsperpacket,
,
"Maximum number of IPv4 fragments allowed per packet  
)

◆ sysctl_maxfragbucketsize()

static int sysctl_maxfragbucketsize ( SYSCTL_HANDLER_ARGS  )
static

Definition at line 848 of file ip_reass.c.

References ipreass_drain_tomax(), and V_ipreass_maxbucketsize.

Here is the call graph for this function:

◆ sysctl_maxfragpackets()

static int sysctl_maxfragpackets ( SYSCTL_HANDLER_ARGS  )
static

Definition at line 751 of file ip_reass.c.

References ipreass_drain(), ipreass_drain_tomax(), IPREASS_NHASH, V_ipq_zone, V_ipreass_maxbucketsize, and V_noreass.

Here is the call graph for this function:

◆ SYSCTL_PROC() [1/2]

SYSCTL_PROC ( _net_inet_ip  ,
OID_AUTO  ,
maxfragbucketsize  ,
CTLFLAG_VNET|CTLTYPE_INT|CTLFLAG_MPSAFE|  CTLFLAG_RW,
NULL  ,
,
sysctl_maxfragbucketsize  ,
"I"  ,
"Maximum number of IPv4 fragment reassembly queue entries per bucket  
)

◆ SYSCTL_PROC() [2/2]

SYSCTL_PROC ( _net_inet_ip  ,
OID_AUTO  ,
maxfragpackets  ,
CTLFLAG_VNET|CTLTYPE_INT|CTLFLAG_RW|  CTLFLAG_NEEDGIANT,
NULL  ,
,
sysctl_maxfragpackets  ,
"I"  ,
"Maximum number of IPv4 fragment reassembly queue entries"   
)

◆ SYSCTL_UINT()

SYSCTL_UINT ( _net_inet_ip  ,
OID_AUTO  ,
curfrags  ,
CTLFLAG_RD  ,
nfrags,
,
"Current number of IPv4 fragments across all reassembly queues"   
)

◆ SYSCTL_UMA_CUR()

SYSCTL_UMA_CUR ( _net_inet_ip  ,
OID_AUTO  ,
fragpackets  ,
CTLFLAG_VNET  ,
VNET_NAMEipq_zone,
"Current number of IPv4 fragment reassembly queue entries"   
)

◆ VNET_DEFINE_STATIC() [1/6]

VNET_DEFINE_STATIC ( int  ,
ipreass_maxbucketsize   
)

◆ VNET_DEFINE_STATIC() [2/6]

VNET_DEFINE_STATIC ( int  ,
maxfragsperpacket   
)

◆ VNET_DEFINE_STATIC() [3/6]

VNET_DEFINE_STATIC ( int  ,
noreass   
)

◆ VNET_DEFINE_STATIC() [4/6]

VNET_DEFINE_STATIC ( struct ipqbucket  ,
ipq  [IPREASS_NHASH] 
)

◆ VNET_DEFINE_STATIC() [5/6]

VNET_DEFINE_STATIC ( uint32_t  ,
ipq_hashseed   
)

◆ VNET_DEFINE_STATIC() [6/6]

VNET_DEFINE_STATIC ( uma_zone_t  ,
ipq_zone   
)

Variable Documentation

◆ maxfrags

int maxfrags
static

Definition at line 139 of file ip_reass.c.

Referenced by ip_reass(), ipreass_init(), and ipreass_zone_change().

◆ nfrags

u_int __exclusive_cache_line nfrags
static

Definition at line 140 of file ip_reass.c.

Referenced by ip_fragment(), ip_reass(), ipq_free(), ipq_reuse(), and ipreass_slowtimo().