The FreeBSD kernel provides the following functions for working with ifnet
structures:
#include <net/if.h> #include <net/if_types.h> #include <net/if_var.h> struct ifnet * if_alloc(u_char type); void if_initname(struct ifnet *ifp, const char *name, int unit); void if_attach(struct ifnet *ifp); void if_detach(struct ifnet *ifp); void if_free(struct ifnet *ifp);
An ifnet
structure is a dynamically allocated structure that’s owned by the kernel. That is, you cannot allocate a struct ifnet
on your own. Instead, you must call if_alloc
. The type argument is the interface type (for example, Ethernet devices are IFT_ETHER
). Symbolic constants for every interface type can be found in the <net/if_types.h>
header.
Allocating an ifnet
structure does not make the interface available to the system. To do that, you must initialize the structure (by defining the necessary fields) and then call if_attach
.
The if_initname
function is a convenient function for setting an interface’s name and unit number. (Needless to say, this function is used before if_attach
.)
When an ifnet
structure is no longer needed, it should be deactivated with if_detach
, after which it can be freed with if_free
.
The ether_ifattach
function is a variant of if_attach
that’s used for Ethernet devices.
#include <net/if.h> #include <net/if_types.h> #include <net/if_var.h> #include <net/ethernet.h> void ether_ifattach(struct ifnet *ifp, const u_int8_t *lla);
This function is defined in the /sys/net/if_ethersubr.c source file as follows:
void ether_ifattach(struct ifnet *ifp, const u_int8_t *lla) { struct ifaddr *ifa; struct sockaddr_dl *sdl; int i; ifp->if_addrlen = ETHER_ADDR_LEN; ifp->if_hdrlen = ETHER_HDR_LEN; if_attach(ifp); ifp->if_mtu = ETHERMTU; ifp->if_output = ether_output; ifp->if_input = ether_input; ifp->if_resolvemulti = ether_resolvemulti; #ifdef VIMAGE ifp->if_reassign = ether_reassign; #endif if (ifp->if_baudrate == 0) ifp->if_baudrate = IF_Mbps(10); ifp->if_broadcastaddr = etherbroadcastaddr; ifa = ifp->if_addr; KASSERT(ifa != NULL, ("%s: no lladdr! ", __func__)); sdl = (struct sockaddr_dl *)ifa->ifa_addr; sdl->sdl_type = IFT_ETHER; sdl->sdl_alen = ifp->if_addrlen; bcopy(lla, LLADDR(sdl), ifp->if_addrlen); bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN); if (ng_ether_attach_p != NULL) (*ng_ether_attach_p)(ifp); /* Print Ethernet MAC address (if lla is nonzero). */ for (i = 0; i < ifp->if_addrlen; i++) if (lla[i] != 0) break; if (i != ifp->if_addrlen) if_printf(ifp, "Ethernet address: %6D ", lla, ":"); }
This function takes an ifnet structure, ifp, and a link layer address, lla, and sets up ifp
for an Ethernet device.
As you can see, it assigns certain values to ifp
, including assigning the appropriate link layer routine to if_output
, if_input
, if_resolvemulti
, and if_reassign
.
The ether_ifdetach
function is a variant of if_detach
that’s used for Ethernet devices.
#include <net/if.h> #include <net/if_types.h> #include <net/if_var.h> #include <net/ethernet.h> void ether_ifdetach(struct ifnet *ifp);
This function is used to deactivate an ifnet
structure set up by ether_ifattach
.
3.133.147.252