FreeBSD kernel IPv4 code
if_ether.c File Reference
#include <sys/cdefs.h>
#include "opt_inet.h"
#include <sys/param.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/ethernet.h>
#include <net/route.h>
#include <net/route/nhop.h>
#include <net/vnet.h>
#include <netinet/in.h>
#include <netinet/in_fib.h>
#include <netinet/in_var.h>
#include <net/if_llatbl.h>
#include <netinet/if_ether.h>
#include <security/mac/mac_framework.h>
Include dependency graph for if_ether.c:

Go to the source code of this file.

Macros

#define SIN(s)   ((const struct sockaddr_in *)(s))
 
#define V_arpt_keep   VNET(arpt_keep)
 
#define V_arpt_down   VNET(arpt_down)
 
#define V_arpt_rexmit   VNET(arpt_rexmit)
 
#define V_arp_maxtries   VNET(arp_maxtries)
 
#define V_arp_proxyall   VNET(arp_proxyall)
 
#define V_arp_maxhold   VNET(arp_maxhold)
 
#define MAX_GARP_RETRANSMITS   16
 
#define V_arp_log_level   VNET(arp_log_level)
 
#define ARP_LOG(pri, ...)
 

Enumerations

enum  arp_llinfo_state { ARP_LLINFO_INCOMPLETE = 0 , ARP_LLINFO_REACHABLE , ARP_LLINFO_VERIFY , ARP_LLINFO_DELETED }
 

Functions

 __FBSDID ("$FreeBSD$")
 
 SYSCTL_DECL (_net_link_ether)
 
static SYSCTL_NODE (_net_link_ether, PF_INET, inet, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "")
 
static SYSCTL_NODE (_net_link_ether, PF_ARP, arp, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "")
 
 VNET_DEFINE_STATIC (int, arpt_keep)
 
 VNET_DEFINE_STATIC (int, arp_maxtries)
 
 VNET_DEFINE_STATIC (int, arp_proxyall)=0
 
 VNET_DEFINE_STATIC (int, arpt_down)
 
 VNET_DEFINE_STATIC (int, arpt_rexmit)
 
 VNET_PCPUSTAT_DEFINE (struct arpstat, arpstat)
 
 VNET_PCPUSTAT_SYSINIT (arpstat)
 
 VNET_DEFINE_STATIC (int, arp_maxhold)
 
 SYSCTL_INT (_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(arpt_keep), 0, "ARP entry lifetime in seconds")
 
 SYSCTL_INT (_net_link_ether_inet, OID_AUTO, maxtries, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(arp_maxtries), 0, "ARP resolution attempts before returning error")
 
 SYSCTL_INT (_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(arp_proxyall), 0, "Enable proxy ARP for all suitable requests")
 
 SYSCTL_INT (_net_link_ether_inet, OID_AUTO, wait, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(arpt_down), 0, "Incomplete ARP entry lifetime in seconds")
 
 SYSCTL_VNET_PCPUSTAT (_net_link_ether_arp, OID_AUTO, stats, struct arpstat, arpstat, "ARP statistics (struct arpstat, net/if_arp.h)")
 
 SYSCTL_INT (_net_link_ether_inet, OID_AUTO, maxhold, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(arp_maxhold), 0, "Number of packets to hold per ARP entry")
 
 SYSCTL_INT (_net_link_ether_inet, OID_AUTO, max_log_per_second, CTLFLAG_RW, &arp_maxpps, 0, "Maximum number of remotely triggered ARP messages that can be " "logged per second")
 
static int sysctl_garp_rexmit (SYSCTL_HANDLER_ARGS)
 
 SYSCTL_PROC (_net_link_ether_inet, OID_AUTO, garp_rexmit_count, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_MPSAFE, &garp_rexmit_count, 0, sysctl_garp_rexmit, "I", "Number of times to retransmit GARP packets;" " 0 to disable, maximum of 16")
 
 VNET_DEFINE_STATIC (int, arp_log_level)
 
 SYSCTL_INT (_net_link_ether_arp, OID_AUTO, log_level, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(arp_log_level), 0, "Minimum log(9) level for recording rate limited arp log messages. " "The higher will be log more (emerg=0, info=6 (default), debug=7).")
 
static void arpintr (struct mbuf *)
 
static void arptimer (void *)
 
static void arp_check_update_lle (struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp, int bridged, struct llentry *la)
 
static void arp_mark_lle_reachable (struct llentry *la)
 
static void arp_iflladdr (void *arg __unused, struct ifnet *ifp)
 
static int arp_fillheader (struct ifnet *ifp, struct arphdr *ah, int bcast, u_char *buf, size_t *bufsize)
 
static int arprequest_internal (struct ifnet *ifp, const struct in_addr *sip, const struct in_addr *tip, u_char *enaddr)
 
void arprequest (struct ifnet *ifp, const struct in_addr *sip, const struct in_addr *tip, u_char *enaddr)
 
static int arpresolve_full (struct ifnet *ifp, int is_gw, int flags, struct mbuf *m, const struct sockaddr *dst, u_char *desten, uint32_t *pflags, struct llentry **plle)
 
int arpresolve (struct ifnet *ifp, int is_gw, struct mbuf *m, const struct sockaddr *dst, u_char *desten, uint32_t *pflags, struct llentry **plle)
 
static struct mbuf * arp_grab_holdchain (struct llentry *la)
 
static void arp_flush_holdchain (struct ifnet *ifp, struct llentry *la, struct mbuf *chain)
 
static __noinline void arp_add_ifa_lle (struct ifnet *ifp, const struct sockaddr *dst)
 
static void garp_rexmit (void *arg)
 
static void garp_timer_start (struct ifaddr *ifa)
 
void arp_ifinit (struct ifnet *ifp, struct ifaddr *ifa)
 
void arp_announce_ifaddr (struct ifnet *ifp, struct in_addr addr, u_char *enaddr)
 
static __noinline void arp_handle_ifllchange (struct ifnet *ifp)
 
static void vnet_arp_init (void)
 
 VNET_SYSINIT (vnet_arp_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_SECOND, vnet_arp_init, 0)
 

Variables

static struct timeval arp_lastlog
 
static int arp_curpps
 
static int arp_maxpps = 1
 
static int garp_rexmit_count = 0
 
static eventhandler_tag iflladdr_tag
 
static const struct netisr_handler arp_nh
 

Macro Definition Documentation

◆ ARP_LOG

#define ARP_LOG (   pri,
  ... 
)
Value:
do { \
if ((pri) <= V_arp_log_level && \
ppsratecheck(&arp_lastlog, &arp_curpps, arp_maxpps)) \
log((pri), "arp: " __VA_ARGS__); \
} while (0)
static struct timeval arp_lastlog
Definition: if_ether.c:81
static int arp_maxpps
Definition: if_ether.c:83
#define V_arp_log_level
Definition: if_ether.c:170
static int arp_curpps
Definition: if_ether.c:82

Definition at line 175 of file if_ether.c.

◆ MAX_GARP_RETRANSMITS

#define MAX_GARP_RETRANSMITS   16

Definition at line 159 of file if_ether.c.

◆ SIN

#define SIN (   s)    ((const struct sockaddr_in *)(s))

Definition at line 79 of file if_ether.c.

◆ V_arp_log_level

#define V_arp_log_level   VNET(arp_log_level)

Definition at line 170 of file if_ether.c.

◆ V_arp_maxhold

#define V_arp_maxhold   VNET(arp_maxhold)

Definition at line 123 of file if_ether.c.

◆ V_arp_maxtries

#define V_arp_maxtries   VNET(arp_maxtries)

Definition at line 121 of file if_ether.c.

◆ V_arp_proxyall

#define V_arp_proxyall   VNET(arp_proxyall)

Definition at line 122 of file if_ether.c.

◆ V_arpt_down

#define V_arpt_down   VNET(arpt_down)

Definition at line 119 of file if_ether.c.

◆ V_arpt_keep

#define V_arpt_keep   VNET(arpt_keep)

Definition at line 118 of file if_ether.c.

◆ V_arpt_rexmit

#define V_arpt_rexmit   VNET(arpt_rexmit)

Definition at line 120 of file if_ether.c.

Enumeration Type Documentation

◆ arp_llinfo_state

Enumerator
ARP_LLINFO_INCOMPLETE 
ARP_LLINFO_REACHABLE 
ARP_LLINFO_VERIFY 
ARP_LLINFO_DELETED 

Definition at line 86 of file if_ether.c.

Function Documentation

◆ __FBSDID()

__FBSDID ( "$FreeBSD$"  )

◆ arp_add_ifa_lle()

static __noinline void arp_add_ifa_lle ( struct ifnet *  ifp,
const struct sockaddr *  dst 
)
static

Definition at line 1294 of file if_ether.c.

References LLTABLE.

Referenced by arp_ifinit().

Here is the caller graph for this function:

◆ arp_announce_ifaddr()

void arp_announce_ifaddr ( struct ifnet *  ifp,
struct in_addr  addr,
u_char *  enaddr 
)

Definition at line 1462 of file if_ether.c.

References arprequest(), INADDR_ANY, and in_addr::s_addr.

Referenced by arp_ifinit().

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

◆ arp_check_update_lle()

static void arp_check_update_lle ( struct arphdr *  ah,
struct in_addr  isaddr,
struct ifnet *  ifp,
int  bridged,
struct llentry *  la 
)
static

Definition at line 1181 of file if_ether.c.

References arp_flush_holdchain(), arp_grab_holdchain(), ARP_LOG, arp_mark_lle_reachable(), and inet_ntoa_r().

Here is the call graph for this function:

◆ arp_fillheader()

static int arp_fillheader ( struct ifnet *  ifp,
struct arphdr *  ah,
int  bcast,
u_char *  buf,
size_t *  bufsize 
)
static

Definition at line 318 of file if_ether.c.

Referenced by arprequest_internal().

Here is the caller graph for this function:

◆ arp_flush_holdchain()

static void arp_flush_holdchain ( struct ifnet *  ifp,
struct llentry *  la,
struct mbuf *  chain 
)
static

Definition at line 1153 of file if_ether.c.

Referenced by arp_check_update_lle().

Here is the caller graph for this function:

◆ arp_grab_holdchain()

static struct mbuf * arp_grab_holdchain ( struct llentry *  la)
static

Definition at line 1139 of file if_ether.c.

Referenced by arp_check_update_lle().

Here is the caller graph for this function:

◆ arp_handle_ifllchange()

static __noinline void arp_handle_ifllchange ( struct ifnet *  ifp)
static

Definition at line 1474 of file if_ether.c.

References arp_ifinit().

Referenced by arp_iflladdr().

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

◆ arp_ifinit()

void arp_ifinit ( struct ifnet *  ifp,
struct ifaddr *  ifa 
)

Definition at line 1437 of file if_ether.c.

References arp_add_ifa_lle(), arp_announce_ifaddr(), garp_rexmit_count, garp_timer_start(), INADDR_ANY, in_addr::s_addr, and sockaddr_in::sin_addr.

Referenced by arp_handle_ifllchange().

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

◆ arp_iflladdr()

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

Definition at line 1488 of file if_ether.c.

References arp_handle_ifllchange(), and LLTABLE.

Referenced by vnet_arp_init().

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

◆ arp_mark_lle_reachable()

static void arp_mark_lle_reachable ( struct llentry *  la)
static

Definition at line 1266 of file if_ether.c.

References ARP_LLINFO_REACHABLE, arptimer(), V_arp_maxtries, V_arpt_keep, and V_arpt_rexmit.

Referenced by arp_check_update_lle().

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

◆ arpintr()

static void arpintr ( struct mbuf *  m)
static

Definition at line 668 of file if_ether.c.

References ARP_LOG.

◆ arprequest()

void arprequest ( struct ifnet *  ifp,
const struct in_addr sip,
const struct in_addr tip,
u_char *  enaddr 
)

Definition at line 443 of file if_ether.c.

References arprequest_internal().

Referenced by arp_announce_ifaddr(), arptimer(), and garp_rexmit().

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

◆ arprequest_internal()

static int arprequest_internal ( struct ifnet *  ifp,
const struct in_addr sip,
const struct in_addr tip,
u_char *  enaddr 
)
static

Definition at line 348 of file if_ether.c.

References arp_fillheader(), ARP_LOG, IA_MASKSIN, IA_SIN, and in_addr::s_addr.

Referenced by arprequest(), and arpresolve_full().

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

◆ arpresolve()

int arpresolve ( struct ifnet *  ifp,
int  is_gw,
struct mbuf *  m,
const struct sockaddr *  dst,
u_char *  desten,
uint32_t pflags,
struct llentry **  plle 
)

Definition at line 614 of file if_ether.c.

References arpresolve_full(), ETHER_MAP_IP_MULTICAST, LLTABLE, and SIN.

Referenced by toe_l2_resolve().

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

◆ arpresolve_full()

static int arpresolve_full ( struct ifnet *  ifp,
int  is_gw,
int  flags,
struct mbuf *  m,
const struct sockaddr *  dst,
u_char *  desten,
uint32_t pflags,
struct llentry **  plle 
)
static

Definition at line 462 of file if_ether.c.

References arprequest_internal(), arptimer(), inet_ntoa_r(), LLTABLE, next, SIN, V_arp_maxhold, V_arp_maxtries, and V_arpt_down.

Referenced by arpresolve().

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

◆ arptimer()

static void arptimer ( void *  arg)
static

Definition at line 205 of file if_ether.c.

References ARP_LLINFO_DELETED, ARP_LLINFO_INCOMPLETE, ARP_LLINFO_REACHABLE, ARP_LLINFO_VERIFY, arprequest(), and V_arpt_rexmit.

Referenced by arp_mark_lle_reachable(), and arpresolve_full().

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

◆ garp_rexmit()

static void garp_rexmit ( void *  arg)
static

Definition at line 1360 of file if_ether.c.

References arprequest(), garp_rexmit(), garp_rexmit_count, in_ifaddr::ia_garp_count, in_ifaddr::ia_garp_timer, in_ifaddr::ia_ifa, and IA_SIN.

Referenced by garp_rexmit(), and garp_timer_start().

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

◆ garp_timer_start()

static void garp_timer_start ( struct ifaddr *  ifa)
static

Definition at line 1423 of file if_ether.c.

References garp_rexmit(), in_ifaddr::ia_garp_count, in_ifaddr::ia_garp_timer, and in_ifaddr::ia_ifa.

Referenced by arp_ifinit().

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

◆ SYSCTL_DECL()

SYSCTL_DECL ( _net_link_ether  )

◆ sysctl_garp_rexmit()

static int sysctl_garp_rexmit ( SYSCTL_HANDLER_ARGS  )
static

Definition at line 1334 of file if_ether.c.

References MAX_GARP_RETRANSMITS.

◆ SYSCTL_INT() [1/7]

SYSCTL_INT ( _net_link_ether_arp  ,
OID_AUTO  ,
log_level  ,
CTLFLAG_VNET|  CTLFLAG_RW,
VNET_NAMEarp_log_level,
,
"Minimum log(9) level for recording rate limited arp log messages. " "The higher will be log more (emerg=0, info=6 (default), debug=7)."   
)

◆ SYSCTL_INT() [2/7]

SYSCTL_INT ( _net_link_ether_inet  ,
OID_AUTO  ,
max_age  ,
CTLFLAG_VNET|  CTLFLAG_RW,
VNET_NAMEarpt_keep,
,
"ARP entry lifetime in seconds"   
)

◆ SYSCTL_INT() [3/7]

SYSCTL_INT ( _net_link_ether_inet  ,
OID_AUTO  ,
max_log_per_second  ,
CTLFLAG_RW  ,
arp_maxpps,
,
"Maximum number of remotely triggered ARP messages that can be " "logged per second"   
)

◆ SYSCTL_INT() [4/7]

SYSCTL_INT ( _net_link_ether_inet  ,
OID_AUTO  ,
maxhold  ,
CTLFLAG_VNET|  CTLFLAG_RW,
VNET_NAMEarp_maxhold,
,
"Number of packets to hold per ARP entry"   
)

◆ SYSCTL_INT() [5/7]

SYSCTL_INT ( _net_link_ether_inet  ,
OID_AUTO  ,
maxtries  ,
CTLFLAG_VNET|  CTLFLAG_RW,
VNET_NAMEarp_maxtries,
,
"ARP resolution attempts before returning error"   
)

◆ SYSCTL_INT() [6/7]

SYSCTL_INT ( _net_link_ether_inet  ,
OID_AUTO  ,
proxyall  ,
CTLFLAG_VNET|  CTLFLAG_RW,
VNET_NAMEarp_proxyall,
,
"Enable proxy ARP for all suitable requests"   
)

◆ SYSCTL_INT() [7/7]

SYSCTL_INT ( _net_link_ether_inet  ,
OID_AUTO  ,
wait  ,
CTLFLAG_VNET|  CTLFLAG_RW,
VNET_NAMEarpt_down,
,
"Incomplete ARP entry lifetime in seconds"   
)

◆ SYSCTL_NODE() [1/2]

static SYSCTL_NODE ( _net_link_ether  ,
PF_ARP  ,
arp  ,
CTLFLAG_RW|  CTLFLAG_MPSAFE,
,
""   
)
static

◆ SYSCTL_NODE() [2/2]

static SYSCTL_NODE ( _net_link_ether  ,
PF_INET  ,
inet  ,
CTLFLAG_RW|  CTLFLAG_MPSAFE,
,
""   
)
static

◆ SYSCTL_PROC()

SYSCTL_PROC ( _net_link_ether_inet  ,
OID_AUTO  ,
garp_rexmit_count  ,
CTLTYPE_INT|CTLFLAG_RW|  CTLFLAG_MPSAFE,
garp_rexmit_count,
,
sysctl_garp_rexmit  ,
"I"  ,
"Number of times to retransmit GARP packets;" " 0 to  disable,
maximum of 16"   
)

◆ SYSCTL_VNET_PCPUSTAT()

SYSCTL_VNET_PCPUSTAT ( _net_link_ether_arp  ,
OID_AUTO  ,
stats  ,
struct arpstat  ,
arpstat  ,
"ARP statistics (struct arpstat, net/if_arp.h)"   
)

◆ vnet_arp_init()

static void vnet_arp_init ( void  )
static

Definition at line 1502 of file if_ether.c.

References arp_iflladdr(), arp_nh, and iflladdr_tag.

Here is the call graph for this function:

◆ VNET_DEFINE_STATIC() [1/7]

VNET_DEFINE_STATIC ( int  ,
arp_log_level   
)

◆ VNET_DEFINE_STATIC() [2/7]

VNET_DEFINE_STATIC ( int  ,
arp_maxhold   
)

◆ VNET_DEFINE_STATIC() [3/7]

VNET_DEFINE_STATIC ( int  ,
arp_maxtries   
)

◆ VNET_DEFINE_STATIC() [4/7]

VNET_DEFINE_STATIC ( int  ,
arp_proxyall   
)
pure virtual

◆ VNET_DEFINE_STATIC() [5/7]

VNET_DEFINE_STATIC ( int  ,
arpt_down   
)

◆ VNET_DEFINE_STATIC() [6/7]

VNET_DEFINE_STATIC ( int  ,
arpt_keep   
)

◆ VNET_DEFINE_STATIC() [7/7]

VNET_DEFINE_STATIC ( int  ,
arpt_rexmit   
)

◆ VNET_PCPUSTAT_DEFINE()

VNET_PCPUSTAT_DEFINE ( struct arpstat  ,
arpstat   
)

◆ VNET_PCPUSTAT_SYSINIT()

VNET_PCPUSTAT_SYSINIT ( arpstat  )

◆ VNET_SYSINIT()

VNET_SYSINIT ( vnet_arp_init  ,
SI_SUB_PROTO_DOMAIN  ,
SI_ORDER_SECOND  ,
vnet_arp_init  ,
 
)

Variable Documentation

◆ arp_curpps

int arp_curpps
static

Definition at line 82 of file if_ether.c.

◆ arp_lastlog

struct timeval arp_lastlog
static

Definition at line 81 of file if_ether.c.

◆ arp_maxpps

int arp_maxpps = 1
static

Definition at line 83 of file if_ether.c.

◆ arp_nh

const struct netisr_handler arp_nh
static
Initial value:
= {
.nh_name = "arp",
.nh_handler = arpintr,
.nh_proto = NETISR_ARP,
.nh_policy = NETISR_POLICY_SOURCE,
}
static void arpintr(struct mbuf *)
Definition: if_ether.c:668

Definition at line 194 of file if_ether.c.

Referenced by vnet_arp_init().

◆ garp_rexmit_count

int garp_rexmit_count = 0
static

Definition at line 161 of file if_ether.c.

Referenced by arp_ifinit(), and garp_rexmit().

◆ iflladdr_tag

eventhandler_tag iflladdr_tag
static

Definition at line 192 of file if_ether.c.

Referenced by vnet_arp_init().