git: eb1da3e52582 - main - DrvAPI: Extend driver KPI with more accessors
Date: Tue, 20 Dec 2022 16:23:35 UTC
The branch main has been updated by jhibbits:
URL: https://cgit.FreeBSD.org/src/commit/?id=eb1da3e5258238e1c0555c6a006a341df0821d8e
commit eb1da3e5258238e1c0555c6a006a341df0821d8e
Author: Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2022-12-09 20:54:51 +0000
Commit: Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2022-12-20 16:18:50 +0000
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
---
sys/net/if.c | 147 +++++++++++++++++++++++++++++++++++++++++++++----------
sys/net/if.h | 5 +-
sys/net/if_var.h | 64 ++++++++++++++----------
3 files changed, 162 insertions(+), 54 deletions(-)
diff --git a/sys/net/if.c b/sys/net/if.c
index 970d1398f870..2e2fbdd1d8c3 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -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)
{
diff --git a/sys/net/if.h b/sys/net/if.h
index 117b0e14ef05..0faf159ff1aa 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -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)
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 859abf8fc089..6ec95da4c0cd 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -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 *);