DrvAPI: Extend driver KPI with more accessors

Summary:
Add the following accessors to hide some more netstack details:
* if_get/setcapabilities2 and *bits analogue
* if_setdname
* if_getxname
* if_transmit - wrapper for call to ifp->if_transmit()
- This required changing the existing if_transmit to
if_transmit_default, since that's its purpose.
* if_getalloctype
* if_getindex
* if_foreach_addr_type - Like if_foreach_lladdr() but for any address
  family type.  Used by some drivers to iterate over all AF_INET
  addresses.
* if_init() - wrapper for ifp->if_init() call
* if_setinputfn
* if_setsndtagallocfn
* if_togglehwassist

Reviewers: #transport, #network, glebius, melifaro

Reviewed by:	#network, melifaro
Sponsored by:	Juniper Networks, Inc.
Differential Revision: https://reviews.freebsd.org/D37664
This commit is contained in:
Justin Hibbits 2022-12-09 15:54:51 -05:00
parent e81fcbece8
commit eb1da3e525
3 changed files with 162 additions and 54 deletions

View File

@ -279,7 +279,7 @@ static void if_input_default(struct ifnet *, struct mbuf *);
static int if_requestencap_default(struct ifnet *, struct if_encap_req *);
static void if_route(struct ifnet *, int flag, int fam);
static int if_setflag(struct ifnet *, int, int, int *, int);
static int if_transmit(struct ifnet *ifp, struct mbuf *m);
static int if_transmit_default(struct ifnet *ifp, struct mbuf *m);
static void if_unroute(struct ifnet *, int flag, int fam);
static int if_delmulti_locked(struct ifnet *, struct ifmultiaddr *, int);
static void do_link_state_change(void *, int);
@ -421,13 +421,13 @@ ifnet_byindexgen(uint16_t idx, uint16_t gen)
*/
static void
if_init(void *arg __unused)
if_init_idxtable(void *arg __unused)
{
ifindex_table = malloc(if_indexlim * sizeof(*ifindex_table),
M_IFNET, M_WAITOK | M_ZERO);
}
SYSINIT(if_init, SI_SUB_INIT_IF, SI_ORDER_SECOND, if_init, NULL);
SYSINIT(if_init, SI_SUB_INIT_IF, SI_ORDER_SECOND, if_init_idxtable, NULL);
static void
vnet_if_init(const void *unused __unused)
@ -854,7 +854,7 @@ if_attach_internal(struct ifnet *ifp, bool vmove)
(ifp->if_transmit != NULL && ifp->if_qflush != NULL),
("transmit and qflush must both either be set or both be NULL"));
if (ifp->if_transmit == NULL) {
ifp->if_transmit = if_transmit;
ifp->if_transmit = if_transmit_default;
ifp->if_qflush = if_qflush;
}
if (ifp->if_input == NULL)
@ -2385,7 +2385,7 @@ ifr_data_get_ptr(void *ifrp)
}
struct ifcap_nv_bit_name {
int cap_bit;
uint64_t cap_bit;
const char *cap_name;
};
#define CAPNV(x) {.cap_bit = IFCAP_##x, \
@ -4109,7 +4109,7 @@ if_start(struct ifnet *ifp)
* that have not implemented it
*/
static int
if_transmit(struct ifnet *ifp, struct mbuf *m)
if_transmit_default(struct ifnet *ifp, struct mbuf *m)
{
int error;
@ -4195,7 +4195,7 @@ if_setbaudrate(struct ifnet *ifp, uint64_t baudrate)
}
uint64_t
if_getbaudrate(if_t ifp)
if_getbaudrate(const if_t ifp)
{
return (((struct ifnet *)ifp)->if_baudrate);
@ -4218,7 +4218,7 @@ if_setcapabilitiesbit(if_t ifp, int setbit, int clearbit)
}
int
if_getcapabilities(if_t ifp)
if_getcapabilities(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_capabilities;
}
@ -4242,11 +4242,33 @@ if_setcapenablebit(if_t ifp, int setcap, int clearcap)
}
const char *
if_getdname(if_t ifp)
if_getdname(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_dname;
}
void
if_setdname(if_t ifp, const char *dname)
{
((struct ifnet *)ifp)->if_dname = dname;
}
const char *
if_name(if_t ifp)
{
return ((struct ifnet *)ifp)->if_xname;
}
int
if_setname(if_t ifp, const char *name)
{
if (strlen(name) > sizeof(ifp->if_xname) - 1)
return (ENAMETOOLONG);
strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
return (0);
}
int
if_togglecapenable(if_t ifp, int togglecap)
{
@ -4255,11 +4277,23 @@ if_togglecapenable(if_t ifp, int togglecap)
}
int
if_getcapenable(if_t ifp)
if_getcapenable(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_capenable;
}
int
if_getdunit(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_dunit;
}
int
if_getindex(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_index;
}
void
if_setdescr(if_t ifp, char *descrbuf)
{
@ -4284,6 +4318,12 @@ if_freedescr(char *descrbuf)
free(descrbuf, M_IFDESCR);
}
int
if_getalloctype(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_alloctype;
}
/*
* This is largely undesirable because it ties ifnet to a device, but does
* provide flexiblity for an embedded product vendor. Should be used with
@ -4306,7 +4346,7 @@ if_setdrvflagbits(if_t ifp, int set_flags, int clear_flags)
}
int
if_getdrvflags(if_t ifp)
if_getdrvflags(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_drv_flags;
}
@ -4336,7 +4376,7 @@ if_setflagbits(if_t ifp, int set, int clear)
}
int
if_getflags(if_t ifp)
if_getflags(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_flags;
}
@ -4365,11 +4405,18 @@ if_sethwassist(if_t ifp, int hwassist_bit)
}
int
if_gethwassist(if_t ifp)
if_gethwassist(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_hwassist;
}
int
if_togglehwassist(if_t ifp, int toggle_bits)
{
((struct ifnet *)ifp)->if_hwassist ^= toggle_bits;
return (0);
}
int
if_setmtu(if_t ifp, int mtu)
{
@ -4378,13 +4425,13 @@ if_setmtu(if_t ifp, int mtu)
}
int
if_getmtu(if_t ifp)
if_getmtu(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_mtu;
}
int
if_getmtu_family(if_t ifp, int family)
if_getmtu_family(const if_t ifp, int family)
{
struct domain *dp;
@ -4479,6 +4526,27 @@ if_foreach_llmaddr(if_t ifp, iflladdr_cb_t cb, void *cb_arg)
return (count);
}
u_int
if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg)
{
struct epoch_tracker et;
struct ifaddr *ifa;
u_int count;
MPASS(cb);
count = 0;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != type)
continue;
count += (*cb)(cb_arg, ifa, count);
}
NET_EPOCH_EXIT(et);
return (count);
}
int
if_setsoftc(if_t ifp, void *softc)
{
@ -4487,7 +4555,7 @@ if_setsoftc(if_t ifp, void *softc)
}
void *
if_getsoftc(if_t ifp)
if_getsoftc(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_softc;
}
@ -4520,13 +4588,13 @@ if_sendq_empty(if_t ifp)
}
struct ifaddr *
if_getifaddr(if_t ifp)
if_getifaddr(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_addr;
}
int
if_getamcount(if_t ifp)
if_getamcount(const if_t ifp)
{
return ((struct ifnet *)ifp)->if_amcount;
}
@ -4553,6 +4621,13 @@ if_vlantrunkinuse(if_t ifp)
return ((struct ifnet *)ifp)->if_vlantrunk != NULL?1:0;
}
int
if_init(if_t ifp)
{
(*((struct ifnet *)ifp)->if_init)((struct ifnet *)ifp);
return (0);
}
int
if_input(if_t ifp, struct mbuf* sendmp)
{
@ -4561,6 +4636,13 @@ if_input(if_t ifp, struct mbuf* sendmp)
}
int
if_transmit(if_t ifp, struct mbuf *m)
{
(*((struct ifnet *)ifp)->if_transmit)((struct ifnet *)ifp, m);
return (0);
}
struct mbuf *
if_dequeue(if_t ifp)
{
@ -4585,7 +4667,7 @@ if_setifheaderlen(if_t ifp, int len)
}
caddr_t
if_getlladdr(if_t ifp)
if_getlladdr(const if_t ifp)
{
return (IF_LLADDR((struct ifnet *)ifp));
}
@ -4644,40 +4726,46 @@ if_sethwtsomaxsegsize(if_t ifp, u_int if_hw_tsomaxsegsize)
}
u_int
if_gethwtsomax(if_t ifp)
if_gethwtsomax(const if_t ifp)
{
return (((struct ifnet *)ifp)->if_hw_tsomax);
}
u_int
if_gethwtsomaxsegcount(if_t ifp)
if_gethwtsomaxsegcount(const if_t ifp)
{
return (((struct ifnet *)ifp)->if_hw_tsomaxsegcount);
}
u_int
if_gethwtsomaxsegsize(if_t ifp)
if_gethwtsomaxsegsize(const if_t ifp)
{
return (((struct ifnet *)ifp)->if_hw_tsomaxsegsize);
}
void
if_setinitfn(if_t ifp, void (*init_fn)(void *))
if_setinitfn(if_t ifp, if_init_fn_t init_fn)
{
((struct ifnet *)ifp)->if_init = init_fn;
}
void
if_setioctlfn(if_t ifp, int (*ioctl_fn)(if_t, u_long, caddr_t))
if_setinputfn(if_t ifp, if_input_fn_t input_fn)
{
((struct ifnet *)ifp)->if_input = input_fn;
}
void
if_setioctlfn(if_t ifp, if_ioctl_fn_t ioctl_fn)
{
((struct ifnet *)ifp)->if_ioctl = (void *)ioctl_fn;
}
void
if_setstartfn(if_t ifp, void (*start_fn)(if_t))
if_setstartfn(if_t ifp, if_start_fn_t start_fn)
{
((struct ifnet *)ifp)->if_start = (void *)start_fn;
}
@ -4688,12 +4776,19 @@ if_settransmitfn(if_t ifp, if_transmit_fn_t start_fn)
((struct ifnet *)ifp)->if_transmit = start_fn;
}
void if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn)
void
if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn)
{
((struct ifnet *)ifp)->if_qflush = flush_fn;
}
void
if_setsndtagallocfn(if_t ifp, if_snd_tag_alloc_t alloc_fn)
{
((struct ifnet *)ifp)->if_snd_tag_alloc = alloc_fn;
}
void
if_setgetcounterfn(if_t ifp, if_get_counter_t fn)
{

View File

@ -254,8 +254,9 @@ struct if_data {
#define IFCAP_VXLAN_HWTSO 0x40000000 /* can do IFCAP_TSO on VXLANs */
#define IFCAP_TXTLS_RTLMT 0x80000000 /* can do TLS with rate limiting */
#define IFCAP2_RXTLS4 0x00001
#define IFCAP2_RXTLS6 0x00002
/* IFCAP2_* are integers, not bits. */
#define IFCAP2_RXTLS4 (0x00001ULL << 32)
#define IFCAP2_RXTLS6 (0x00002ULL << 32)
#define IFCAP_HWCSUM_IPV6 (IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6)

View File

@ -129,6 +129,9 @@ typedef struct ifnet * if_t;
typedef void (*if_start_fn_t)(if_t);
typedef int (*if_ioctl_fn_t)(if_t, u_long, caddr_t);
typedef void (*if_init_fn_t)(void *);
typedef void (*if_input_fn_t)(struct ifnet *, struct mbuf *);
typedef int (*if_output_fn_t)
(struct ifnet *, struct mbuf *, const struct sockaddr *, struct route *);
typedef void (*if_qflush_fn_t)(if_t);
typedef int (*if_transmit_fn_t)(if_t, struct mbuf *);
typedef uint64_t (*if_get_counter_t)(if_t, ift_counter);
@ -402,11 +405,8 @@ struct ifnet {
struct netmap_adapter *if_netmap; /* netmap(4) softc */
/* Various procedures of the layer2 encapsulation and drivers. */
int (*if_output) /* output routine (enqueue) */
(struct ifnet *, struct mbuf *, const struct sockaddr *,
struct route *);
void (*if_input) /* input routine (from h/w driver) */
(struct ifnet *, struct mbuf *);
if_output_fn_t if_output; /* output routine (enqueue) */
if_input_fn_t if_input; /* input routine (from h/w driver) */
struct mbuf *(*if_bridge_input)(struct ifnet *, struct mbuf *);
int (*if_bridge_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
@ -477,9 +477,6 @@ struct ifnet {
int if_ispare[4]; /* general use */
};
/* for compatibility with other BSDs */
#define if_name(ifp) ((ifp)->if_xname)
#define IF_NODOM 255
/*
* Locks for address lists on the network interface.
@ -730,44 +727,51 @@ void if_inc_counter(struct ifnet *, ift_counter, int64_t);
LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
uint64_t if_setbaudrate(if_t ifp, uint64_t baudrate);
uint64_t if_getbaudrate(if_t ifp);
uint64_t if_getbaudrate(const if_t ifp);
int if_setcapabilities(if_t ifp, int capabilities);
int if_setcapabilitiesbit(if_t ifp, int setbit, int clearbit);
int if_getcapabilities(if_t ifp);
int if_getcapabilities(const if_t ifp);
int if_togglecapenable(if_t ifp, int togglecap);
int if_setcapenable(if_t ifp, int capenable);
int if_setcapenablebit(if_t ifp, int setcap, int clearcap);
int if_getcapenable(if_t ifp);
const char *if_getdname(if_t ifp);
int if_getcapenable(const if_t ifp);
int if_getdunit(const if_t ifp);
int if_getindex(const if_t ifp);
const char *if_getdname(const if_t ifp);
void if_setdname(if_t ifp, const char *name);
const char *if_name(if_t ifp);
int if_setname(if_t ifp, const char *name);
void if_setdescr(if_t ifp, char *descrbuf);
char *if_allocdescr(size_t sz, int malloc_flag);
void if_freedescr(char *descrbuf);
int if_getalloctype(const if_t ifp);
int if_setdev(if_t ifp, void *dev);
int if_setdrvflagbits(if_t ifp, int if_setflags, int clear_flags);
int if_getdrvflags(if_t ifp);
int if_getdrvflags(const if_t ifp);
int if_setdrvflags(if_t ifp, int flags);
int if_clearhwassist(if_t ifp);
int if_sethwassistbits(if_t ifp, int toset, int toclear);
int if_sethwassist(if_t ifp, int hwassist_bit);
int if_gethwassist(if_t ifp);
int if_gethwassist(const if_t ifp);
int if_togglehwassist(if_t ifp, int toggle_bits);
int if_setsoftc(if_t ifp, void *softc);
void *if_getsoftc(if_t ifp);
int if_setflags(if_t ifp, int flags);
int if_gethwaddr(if_t ifp, struct ifreq *);
int if_gethwaddr(const if_t ifp, struct ifreq *);
int if_setmtu(if_t ifp, int mtu);
int if_getmtu(if_t ifp);
int if_getmtu_family(if_t ifp, int family);
int if_getmtu(const if_t ifp);
int if_getmtu_family(const if_t ifp, int family);
int if_setflagbits(if_t ifp, int set, int clear);
int if_getflags(if_t ifp);
int if_getflags(const if_t ifp);
int if_sendq_empty(if_t ifp);
int if_setsendqready(if_t ifp);
int if_setsendqlen(if_t ifp, int tx_desc_count);
int if_sethwtsomax(if_t ifp, u_int if_hw_tsomax);
int if_sethwtsomaxsegcount(if_t ifp, u_int if_hw_tsomaxsegcount);
int if_sethwtsomaxsegsize(if_t ifp, u_int if_hw_tsomaxsegsize);
u_int if_gethwtsomax(if_t ifp);
u_int if_gethwtsomaxsegcount(if_t ifp);
u_int if_gethwtsomaxsegsize(if_t ifp);
u_int if_gethwtsomax(const if_t ifp);
u_int if_gethwtsomaxsegcount(const if_t ifp);
u_int if_gethwtsomaxsegsize(const if_t ifp);
int if_input(if_t ifp, struct mbuf* sendmp);
int if_sendq_prepend(if_t ifp, struct mbuf *m);
struct mbuf *if_dequeue(if_t ifp);
@ -776,11 +780,13 @@ void if_setrcvif(struct mbuf *m, if_t ifp);
void if_setvtag(struct mbuf *m, u_int16_t tag);
u_int16_t if_getvtag(struct mbuf *m);
int if_vlantrunkinuse(if_t ifp);
caddr_t if_getlladdr(if_t ifp);
caddr_t if_getlladdr(const if_t ifp);
void *if_gethandle(u_char);
void if_bpfmtap(if_t ifp, struct mbuf *m);
void if_etherbpfmtap(if_t ifp, struct mbuf *m);
void if_vlancap(if_t ifp);
int if_transmit(if_t ifp, struct mbuf *m);
int if_init(if_t ifp);
/*
* Traversing through interface address lists.
@ -792,16 +798,22 @@ u_int if_foreach_llmaddr(if_t, iflladdr_cb_t, void *);
u_int if_lladdr_count(if_t);
u_int if_llmaddr_count(if_t);
int if_getamcount(if_t ifp);
struct ifaddr * if_getifaddr(if_t ifp);
int if_getamcount(const if_t ifp);
struct ifaddr * if_getifaddr(const if_t ifp);
typedef u_int if_addr_cb_t(void *, struct ifaddr *, u_int);
u_int if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg);
/* Functions */
void if_setinitfn(if_t ifp, void (*)(void *));
void if_setioctlfn(if_t ifp, int (*)(if_t, u_long, caddr_t));
void if_setinitfn(if_t ifp, if_init_fn_t);
void if_setinputfn(if_t ifp, if_input_fn_t);
void if_setioctlfn(if_t ifp, if_ioctl_fn_t);
void if_setoutputfn(if_t ifp, int(*)
(if_t, struct mbuf *, const struct sockaddr *, struct route *));
void if_setstartfn(if_t ifp, void (*)(if_t));
void if_settransmitfn(if_t ifp, if_transmit_fn_t);
void if_setqflushfn(if_t ifp, if_qflush_fn_t);
void if_setgetcounterfn(if_t ifp, if_get_counter_t);
void if_setsndtagallocfn(if_t ifp, if_snd_tag_alloc_t);
/* TSO */
void if_hw_tsomax_common(if_t ifp, struct ifnet_hw_tsomax *);