git: eb1da3e52582 - main - DrvAPI: Extend driver KPI with more accessors

From: Justin Hibbits <jhibbits_at_FreeBSD.org>
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 *);