FreeBSD kernel IPv6 code
ip6_output.c File Reference
#include <sys/cdefs.h>
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_kern_tls.h"
#include "opt_ratelimit.h"
#include "opt_route.h"
#include "opt_rss.h"
#include "opt_sctp.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/ktls.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/syslog.h>
#include <sys/ucred.h>
#include <machine/in_cksum.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_vlan_var.h>
#include <net/if_llatbl.h>
#include <net/ethernet.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/route/nhop.h>
#include <net/pfil.h>
#include <net/rss_config.h>
#include <net/vnet.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/ip_var.h>
#include <netinet6/in6_fib.h>
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#include <netinet6/ip6_var.h>
#include <netinet/in_pcb.h>
#include <netinet/tcp_var.h>
#include <netinet6/nd6.h>
#include <netinet6/in6_rss.h>
#include <netipsec/ipsec_support.h>
#include <netinet6/ip6protosw.h>
#include <netinet6/scope6_var.h>
Include dependency graph for ip6_output.c:

Go to the source code of this file.

Data Structures

struct  ip6_exthdrs
 

Macros

#define MAKE_EXTHDR(hp, mp, _ol)
 
#define MAKE_CHAIN(m, mp, p, i)
 
#define JUMBOOPTLEN   8 /* length of jumbo payload option and padding */
 
#define IPV6_PKTOPTIONS_MBUF_LIMIT   ((u_long)nmbclusters * MCLBYTES / 4)
 
#define OPTSET(bit)
 
#define OPTSET2292(bit)
 
#define OPTBIT(bit)   (inp->inp_flags & (bit) ? 1 : 0)
 
#define OPTSET2_N(bit, val)
 
#define OPTSET2(bit, val)
 
#define OPTBIT2(bit)   (inp->inp_flags2 & (bit) ? 1 : 0)
 
#define OPTSET2292_EXCLUSIVE(bit)
 
#define GET_PKTOPT_VAR(field, lenexpr)
 
#define GET_PKTOPT_EXT_HDR(field)
 
#define GET_PKTOPT_SOCKADDR(field)
 
#define PKTOPT_EXTHDRCPY(type)
 
#define elen(x)    (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
 

Functions

 __FBSDID ("$FreeBSD$")
 
static MALLOC_DEFINE (M_IP6OPT, "ip6opt", "IPv6 options")
 
static int ip6_pcbopt (int, u_char *, int, struct ip6_pktopts **, struct ucred *, int)
 
static int ip6_pcbopts (struct ip6_pktopts **, struct mbuf *, struct socket *, struct sockopt *)
 
static int ip6_getpcbopt (struct inpcb *, int, struct sockopt *)
 
static int ip6_setpktopt (int, u_char *, int, struct ip6_pktopts *, struct ucred *, int, int, int)
 
static int ip6_copyexthdr (struct mbuf **, caddr_t, int)
 
static int ip6_insertfraghdr (struct mbuf *, struct mbuf *, int, struct ip6_frag **)
 
static int ip6_insert_jumboopt (struct ip6_exthdrs *, u_int32_t)
 
static int ip6_splithdr (struct mbuf *, struct ip6_exthdrs *)
 
static int ip6_getpmtu (struct route_in6 *, int, struct ifnet *, const struct in6_addr *, u_long *, int *, u_int, u_int)
 
static int ip6_calcmtu (struct ifnet *, const struct in6_addr *, u_long, u_long *, int *, u_int)
 
static int ip6_getpmtu_ctl (u_int, const struct in6_addr *, u_long *)
 
static int copypktopts (struct ip6_pktopts *, struct ip6_pktopts *, int)
 
void in6_delayed_cksum (struct mbuf *m, uint32_t plen, u_short offset)
 
static void ip6_output_delayed_csum (struct mbuf *m, struct ifnet *ifp, int csum_flags, int plen, int optlen)
 
int ip6_fragment (struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto, int fraglen, uint32_t id)
 
static int ip6_output_send (struct inpcb *inp, struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, struct sockaddr_in6 *dst, struct route_in6 *ro, bool stamp_tag)
 
int ip6_output (struct mbuf *m0, struct ip6_pktopts *opt, struct route_in6 *ro, int flags, struct ip6_moptions *im6o, struct ifnet **ifpp, struct inpcb *inp)
 
int ip6_ctloutput (struct socket *so, struct sockopt *sopt)
 
int ip6_raw_ctloutput (struct socket *so, struct sockopt *sopt)
 
void ip6_initpktopts (struct ip6_pktopts *opt)
 
void ip6_clearpktopts (struct ip6_pktopts *pktopt, int optname)
 
struct ip6_pktoptsip6_copypktopts (struct ip6_pktopts *src, int canwait)
 
void ip6_freepcbopts (struct ip6_pktopts *pktopt)
 
int ip6_setpktopts (struct mbuf *control, struct ip6_pktopts *opt, struct ip6_pktopts *stickyopt, struct ucred *cred, int uproto)
 
void ip6_mloopback (struct ifnet *ifp, struct mbuf *m)
 
int ip6_optlen (struct inpcb *inp)
 

Variables

int in6_mcast_loop
 

Macro Definition Documentation

◆ elen

#define elen (   x)     (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)

◆ GET_PKTOPT_EXT_HDR

#define GET_PKTOPT_EXT_HDR (   field)
Value:
GET_PKTOPT_VAR(field, \
(((struct ip6_ext *)pktopt->field)->ip6e_len + 1) << 3)
#define GET_PKTOPT_VAR(field, lenexpr)
Definition: ip6_output.c:2571

Definition at line 2594 of file ip6_output.c.

◆ GET_PKTOPT_SOCKADDR

#define GET_PKTOPT_SOCKADDR (   field)
Value:
GET_PKTOPT_VAR(field, \
pktopt->field->sa_len)

Definition at line 2597 of file ip6_output.c.

◆ GET_PKTOPT_VAR

#define GET_PKTOPT_VAR (   field,
  lenexpr 
)
Value:
do { \
if (pktopt && pktopt->field) { \
INP_RUNLOCK(inp); \
optdata = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK); \
malloc_optdata = true; \
INP_RLOCK(inp); \
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { \
INP_RUNLOCK(inp); \
free(optdata, M_TEMP); \
return (ECONNRESET); \
} \
pktopt = inp->in6p_outputopts; \
if (pktopt && pktopt->field) { \
optdatalen = min(lenexpr, sopt->sopt_valsize); \
bcopy(pktopt->field, optdata, optdatalen); \
} else { \
free(optdata, M_TEMP); \
optdata = NULL; \
malloc_optdata = false; \
} \
} \
} while(0)

Definition at line 2571 of file ip6_output.c.

◆ IPV6_PKTOPTIONS_MBUF_LIMIT

#define IPV6_PKTOPTIONS_MBUF_LIMIT   ((u_long)nmbclusters * MCLBYTES / 4)

◆ JUMBOOPTLEN

#define JUMBOOPTLEN   8 /* length of jumbo payload option and padding */

◆ MAKE_CHAIN

#define MAKE_CHAIN (   m,
  mp,
  p,
 
)
Value:
do {\
if (m) {\
if (!hdrsplit) \
panic("%s:%d: assumption failed: "\
"hdr not split: hdrsplit %d exthdrs %p",\
__func__, __LINE__, hdrsplit, &exthdrs);\
*mtod((m), u_char *) = *(p);\
*(p) = (i);\
p = mtod((m), u_char *);\
(m)->m_next = (mp)->m_next;\
(mp)->m_next = (m);\
(mp) = (m);\
}\
} while (/*CONSTCOND*/ 0)

Definition at line 183 of file ip6_output.c.

◆ MAKE_EXTHDR

#define MAKE_EXTHDR (   hp,
  mp,
  _ol 
)
Value:
do { \
if (hp) { \
struct ip6_ext *eh = (struct ip6_ext *)(hp); \
error = ip6_copyexthdr((mp), (caddr_t)(hp), \
((eh)->ip6e_len + 1) << 3); \
if (error) \
goto freehdrs; \
(_ol) += (*(mp))->m_len; \
} \
} while (/*CONSTCOND*/ 0)
static int ip6_copyexthdr(struct mbuf **, caddr_t, int)
Definition: ip6_output.c:1292

Definition at line 164 of file ip6_output.c.

◆ OPTBIT

#define OPTBIT (   bit)    (inp->inp_flags & (bit) ? 1 : 0)

◆ OPTBIT2

#define OPTBIT2 (   bit)    (inp->inp_flags2 & (bit) ? 1 : 0)

◆ OPTSET

#define OPTSET (   bit)
Value:
do { \
INP_WLOCK(inp); \
if (optval) \
inp->inp_flags |= (bit); \
else \
inp->inp_flags &= ~(bit); \
INP_WUNLOCK(inp); \
} while (/*CONSTCOND*/ 0)

◆ OPTSET2

#define OPTSET2 (   bit,
  val 
)
Value:
do { \
INP_WLOCK(inp); \
OPTSET2_N(bit, val); \
INP_WUNLOCK(inp); \
} while (0)

◆ OPTSET2292

#define OPTSET2292 (   bit)
Value:
do { \
INP_WLOCK(inp); \
inp->inp_flags |= IN6P_RFC2292; \
if (optval) \
inp->inp_flags |= (bit); \
else \
inp->inp_flags &= ~(bit); \
INP_WUNLOCK(inp); \
} while (/*CONSTCOND*/ 0)

◆ OPTSET2292_EXCLUSIVE

#define OPTSET2292_EXCLUSIVE (   bit)
Value:
do { \
INP_WLOCK(inp); \
if (OPTBIT(IN6P_RFC2292)) { \
error = EINVAL; \
} else { \
if (optval) \
inp->inp_flags |= (bit); \
else \
inp->inp_flags &= ~(bit); \
} \
INP_WUNLOCK(inp); \
} while (/*CONSTCOND*/ 0)
#define OPTBIT(bit)

◆ OPTSET2_N

#define OPTSET2_N (   bit,
  val 
)
Value:
do { \
if (val) \
inp->inp_flags2 |= bit; \
else \
inp->inp_flags2 &= ~bit; \
} while (0)

◆ PKTOPT_EXTHDRCPY

#define PKTOPT_EXTHDRCPY (   type)
Value:
do {\
if (src->type) {\
int hlen = (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\
dst->type = malloc(hlen, M_IP6OPT, canwait);\
if (dst->type == NULL)\
goto bad;\
bcopy(src->type, dst->type, hlen);\
}\
} while (/*CONSTCOND*/ 0)

Definition at line 2736 of file ip6_output.c.

Function Documentation

◆ __FBSDID()

__FBSDID ( "$FreeBSD$"  )

◆ copypktopts()

static int copypktopts ( struct ip6_pktopts dst,
struct ip6_pktopts src,
int  canwait 
)
static

Definition at line 2748 of file ip6_output.c.

References ip6_clearpktopts(), ip6_pktopts::ip6po_flags, ip6_pktopts::ip6po_hlim, ip6_pktopts::ip6po_minmtu, ip6_pktopts::ip6po_pktinfo, ip6_pktopts::ip6po_prefer_tempaddr, ip6po_rthdr, ip6_pktopts::ip6po_tclass, and PKTOPT_EXTHDRCPY.

Referenced by ip6_copypktopts(), and ip6_setpktopts().

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

◆ in6_delayed_cksum()

void in6_delayed_cksum ( struct mbuf *  m,
uint32_t  plen,
u_short  offset 
)

Definition at line 200 of file ip6_output.c.

Referenced by ip6_output_delayed_csum().

Here is the caller graph for this function:

◆ ip6_calcmtu()

static int ip6_calcmtu ( struct ifnet *  ifp,
const struct in6_addr dst,
u_long  rt_mtu,
u_long *  mtup,
int *  alwaysfragp,
u_int  proto 
)
static

Definition at line 1541 of file ip6_output.c.

References IN6_LINKMTU.

Referenced by ip6_getpmtu(), and ip6_getpmtu_ctl().

Here is the caller graph for this function:

◆ ip6_clearpktopts()

◆ ip6_copyexthdr()

static int ip6_copyexthdr ( struct mbuf **  mp,
caddr_t  hdr,
int  hlen 
)
static

Definition at line 1292 of file ip6_output.c.

◆ ip6_copypktopts()

struct ip6_pktopts * ip6_copypktopts ( struct ip6_pktopts src,
int  canwait 
)

Definition at line 2788 of file ip6_output.c.

References copypktopts(), and ip6_initpktopts().

Here is the call graph for this function:

◆ ip6_ctloutput()

◆ ip6_fragment()

int ip6_fragment ( struct ifnet *  ifp,
struct mbuf *  m0,
int  hlen,
u_char  nextproto,
int  fraglen,
uint32_t  id 
)

Definition at line 238 of file ip6_output.c.

References in6_ifstat_inc, ip6_insertfraghdr(), and IP6STAT_INC.

Referenced by ip6_output().

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

◆ ip6_freepcbopts()

void ip6_freepcbopts ( struct ip6_pktopts pktopt)

Definition at line 2807 of file ip6_output.c.

References ip6_clearpktopts().

Here is the call graph for this function:

◆ ip6_getpcbopt()

◆ ip6_getpmtu()

static int ip6_getpmtu ( struct route_in6 *  ro_pmtu,
int  do_lookup,
struct ifnet *  ifp,
const struct in6_addr dst,
u_long *  mtup,
int *  alwaysfragp,
u_int  fibnum,
u_int  proto 
)
static

Definition at line 1484 of file ip6_output.c.

References fib6_lookup(), IN6_ARE_ADDR_EQUAL, in6_splitscope(), ip6_calcmtu(), sin6, sockaddr_in6::sin6_addr, sockaddr_in6::sin6_family, and sockaddr_in6::sin6_len.

Referenced by ip6_output().

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

◆ ip6_getpmtu_ctl()

static int ip6_getpmtu_ctl ( u_int  fibnum,
const struct in6_addr dst,
u_long *  mtup 
)
static

Definition at line 1452 of file ip6_output.c.

References fib6_lookup(), in6_splitscope(), and ip6_calcmtu().

Referenced by ip6_ctloutput().

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

◆ ip6_initpktopts()

void ip6_initpktopts ( struct ip6_pktopts opt)

◆ ip6_insert_jumboopt()

static int ip6_insert_jumboopt ( struct ip6_exthdrs exthdrs,
u_int32_t  plen 
)
static

Definition at line 1317 of file ip6_output.c.

References ip6_exthdrs::ip6e_hbh, ip6_exthdrs::ip6e_ip6, and JUMBOOPTLEN.

Referenced by ip6_output().

Here is the caller graph for this function:

◆ ip6_insertfraghdr()

static int ip6_insertfraghdr ( struct mbuf *  m0,
struct mbuf *  m,
int  hlen,
struct ip6_frag **  frghdrp 
)
static

Definition at line 1405 of file ip6_output.c.

Referenced by ip6_fragment().

Here is the caller graph for this function:

◆ ip6_mloopback()

void ip6_mloopback ( struct ifnet *  ifp,
struct mbuf *  m 
)

Definition at line 3297 of file ip6_output.c.

References in6_clearscope().

Referenced by ip6_output(), and phyint_send().

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

◆ ip6_optlen()

int ip6_optlen ( struct inpcb *  inp)

Definition at line 3365 of file ip6_output.c.

References elen.

◆ ip6_output()

int ip6_output ( struct mbuf *  m0,
struct ip6_pktopts opt,
struct route_in6 *  ro,
int  flags,
struct ip6_moptions *  im6o,
struct ifnet **  ifpp,
struct inpcb *  inp 
)

Definition at line 409 of file ip6_output.c.

References fib6_lookup(), in6_ifaddr::ia_ifa, ifatoia6, IN6_ARE_ADDR_EQUAL, in6_clearscope(), in6_getlinkifnet(), in6_ifawithifp(), in6_ifstat_inc, IN6_IS_ADDR_MC_INTFACELOCAL, IN6_IS_ADDR_MC_LINKLOCAL, IN6_IS_ADDR_MC_NODELOCAL, IN6_IS_ADDR_MULTICAST, IN6_IS_ADDR_UNSPECIFIED, IN6_LINKMTU, in6_localip(), in6_mcast_loop, in6_selectroute(), in6_setscope(), in6_splitscope(), ip6_fragment(), ip6_getpmtu(), ip6_insert_jumboopt(), ip6_mforward, ip6_mloopback(), ip6_notify_pmtu(), ip6_output_delayed_csum(), ip6_output_send(), ip6_process_hopopts(), ip6_randomid(), ip6_splithdr(), ip6_exthdrs::ip6e_dest1, ip6_exthdrs::ip6e_dest2, ip6_exthdrs::ip6e_hbh, ip6_exthdrs::ip6e_ip6, ip6_exthdrs::ip6e_rthdr, ip6_pktopts::ip6po_dest1, ip6_pktopts::ip6po_dest2, IP6PO_DONTFRAG, ip6_pktopts::ip6po_flags, ip6_pktopts::ip6po_hbh, ip6_pktopts::ip6po_hlim, ip6_pktopts::ip6po_minmtu, IP6PO_MINMTU_ALL, IP6PO_MINMTU_DISABLE, ip6_pktopts::ip6po_tclass, IP6STAT_INC, IPV6_FORWARDING, IPV6_MINMTU, IPV6_UNSPECSRC, M_FASTFWD_OURS, M_IP6_NEXTHOP, M_LOOP, M_SKIP_FIREWALL, MAKE_CHAIN, MAKE_EXTHDR, sa6_recoverscope(), sin6, sockaddr_in6::sin6_addr, sockaddr_in6::sin6_family, sockaddr_in6::sin6_len, sockaddr_in6::sin6_scope_id, V_inet6_pfil_head, V_ip6_defmcasthlim, and V_ip6_mrouter.

Referenced by icmp6_redirect_output(), icmp6_reflect(), in6_gif_output(), in6_gre_output(), mld_dispatch_packet(), nd6_na_output_fib(), nd6_ns_output_fib(), phyint_send(), rip6_output(), and udp6_output().

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

◆ ip6_output_delayed_csum()

static void ip6_output_delayed_csum ( struct mbuf *  m,
struct ifnet *  ifp,
int  csum_flags,
int  plen,
int  optlen 
)
static

Definition at line 216 of file ip6_output.c.

References in6_delayed_cksum().

Referenced by ip6_output().

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

◆ ip6_output_send()

static int ip6_output_send ( struct inpcb *  inp,
struct ifnet *  ifp,
struct ifnet *  origifp,
struct mbuf *  m,
struct sockaddr_in6 dst,
struct route_in6 *  ro,
bool  stamp_tag 
)
static

Definition at line 309 of file ip6_output.c.

References nd6_output_ifp().

Referenced by ip6_output().

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

◆ ip6_pcbopt()

static int ip6_pcbopt ( int  optname,
u_char *  buf,
int  len,
struct ip6_pktopts **  pktopt,
struct ucred *  cred,
int  uproto 
)
static

Definition at line 2548 of file ip6_output.c.

References ip6_initpktopts(), and ip6_setpktopt().

Referenced by ip6_ctloutput().

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

◆ ip6_pcbopts()

static int ip6_pcbopts ( struct ip6_pktopts **  pktopt,
struct mbuf *  m,
struct socket *  so,
struct sockopt *  sopt 
)
static

Definition at line 2485 of file ip6_output.c.

References ip6_clearpktopts(), ip6_setpktopts(), ip6_pktopts::ip6po_dest1, ip6_pktopts::ip6po_dest2, ip6_pktopts::ip6po_hbh, ip6_pktopts::ip6po_pktinfo, ip6po_rhinfo::ip6po_rhi_rthdr, and ip6_pktopts::ip6po_rhinfo.

Referenced by ip6_ctloutput().

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

◆ ip6_raw_ctloutput()

int ip6_raw_ctloutput ( struct socket *  so,
struct sockopt *  sopt 
)

Definition at line 2407 of file ip6_output.c.

References IPV6_CHECKSUM.

Referenced by rip6_ctloutput().

Here is the caller graph for this function:

◆ ip6_setpktopt()

◆ ip6_setpktopts()

int ip6_setpktopts ( struct mbuf *  control,
struct ip6_pktopts opt,
struct ip6_pktopts stickyopt,
struct ucred *  cred,
int  uproto 
)

Definition at line 2821 of file ip6_output.c.

References copypktopts(), ip6_initpktopts(), and ip6_setpktopt().

Referenced by ip6_pcbopts(), rip6_output(), and udp6_output().

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

◆ ip6_splithdr()

static int ip6_splithdr ( struct mbuf *  m,
struct ip6_exthdrs exthdrs 
)
static

Definition at line 3336 of file ip6_output.c.

References ip6_exthdrs::ip6e_ip6.

Referenced by ip6_output().

Here is the caller graph for this function:

◆ MALLOC_DEFINE()

static MALLOC_DEFINE ( M_IP6OPT  ,
"ip6opt"  ,
"IPv6 options"   
)
static

Variable Documentation

◆ in6_mcast_loop

int in6_mcast_loop
extern

Definition at line 186 of file in6_mcast.c.

Referenced by in6p_findmoptions(), ip6_getmoptions(), and ip6_output().