git: f252caf0015a - main - bridge: exterr-ize

From: Lexi Winter <ivy_at_FreeBSD.org>
Date: Mon, 28 Jul 2025 12:46:24 UTC
The branch main has been updated by ivy:

URL: https://cgit.FreeBSD.org/src/commit/?id=f252caf0015a892b2c362719d0098ed654c65bc3

commit f252caf0015a892b2c362719d0098ed654c65bc3
Author:     Lexi Winter <ivy@FreeBSD.org>
AuthorDate: 2025-07-27 15:09:49 +0000
Commit:     Lexi Winter <ivy@FreeBSD.org>
CommitDate: 2025-07-28 09:17:36 +0000

    bridge: exterr-ize
    
    While here, tweak a couple of comments and order includes.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D51181
---
 sys/net/if_bridge.c  | 146 ++++++++++++++++++++++++++++++---------------------
 sys/sys/exterr_cat.h |   1 +
 2 files changed, 88 insertions(+), 59 deletions(-)

diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 5b3ee740d75e..3327c863468f 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -76,31 +76,34 @@
  *	  heterogeneous bridges).
  */
 
-#include <sys/cdefs.h>
 #include "opt_inet.h"
 #include "opt_inet6.h"
 
+#define	EXTERR_CATEGORY	EXTERR_CAT_BRIDGE
+
 #include <sys/param.h>
+#include <sys/ctype.h>  /* string functions */
 #include <sys/eventhandler.h>
-#include <sys/mbuf.h>
+#include <sys/exterrvar.h>
+#include <sys/jail.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
 #include <sys/protosw.h>
+#include <sys/random.h>
 #include <sys/systm.h>
-#include <sys/jail.h>
-#include <sys/time.h>
 #include <sys/socket.h> /* for net/if.h */
 #include <sys/sockio.h>
-#include <sys/ctype.h>  /* string functions */
-#include <sys/kernel.h>
-#include <sys/random.h>
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
+#include <sys/time.h>
+
 #include <vm/uma.h>
-#include <sys/module.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
 
 #include <net/bpf.h>
 #include <net/if.h>
@@ -986,31 +989,37 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 	case SIOCGDRVSPEC:
 	case SIOCSDRVSPEC:
 		if (ifd->ifd_cmd >= bridge_control_table_size) {
-			error = EINVAL;
+			error = EXTERROR(EINVAL, "Invalid control command");
 			break;
 		}
 		bc = &bridge_control_table[ifd->ifd_cmd];
 
 		if (cmd == SIOCGDRVSPEC &&
 		    (bc->bc_flags & BC_F_COPYOUT) == 0) {
-			error = EINVAL;
+			error = EXTERROR(EINVAL,
+			    "Inappropriate ioctl for command "
+			    "(expected SIOCSDRVSPEC)");
 			break;
 		}
 		else if (cmd == SIOCSDRVSPEC &&
 		    (bc->bc_flags & BC_F_COPYOUT) != 0) {
-			error = EINVAL;
+			error = EXTERROR(EINVAL,
+			    "Inappropriate ioctl for command "
+			    "(expected SIOCGDRVSPEC)");
 			break;
 		}
 
 		if (bc->bc_flags & BC_F_SUSER) {
 			error = priv_check(td, PRIV_NET_BRIDGE);
-			if (error)
+			if (error) {
+				EXTERROR(error, "PRIV_NET_BRIDGE required");
 				break;
+			}
 		}
 
 		if (ifd->ifd_len != bc->bc_argsize ||
 		    ifd->ifd_len > sizeof(args)) {
-			error = EINVAL;
+			error = EXTERROR(EINVAL, "Invalid argument size");
 			break;
 		}
 
@@ -1062,7 +1071,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 		oldmtu = sc->sc_ifp->if_mtu;
 
 		if (ifr->ifr_mtu < IF_MINMTU) {
-			error = EINVAL;
+			error = EXTERROR(EINVAL,
+			    "Requested MTU is lower than IF_MINMTU");
 			break;
 		}
 		if (CK_LIST_EMPTY(&sc->sc_iflist)) {
@@ -1088,6 +1098,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 				(*bif->bif_ifp->if_ioctl)(bif->bif_ifp,
 				    SIOCSIFMTU, (caddr_t)ifr);
 			}
+			EXTERROR(error,
+			    "Failed to set MTU on member interface");
 		} else {
 			sc->sc_ifp->if_mtu = ifr->ifr_mtu;
 		}
@@ -1125,14 +1137,14 @@ bridge_mutecaps(struct bridge_softc *sc)
 	mask = BRIDGE_IFCAPS_MASK;
 
 	CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
-		/* Every member must support it or its disabled */
+		/* Every member must support it or it's disabled */
 		mask &= bif->bif_savedcaps;
 	}
 
 	CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 		enabled = bif->bif_ifp->if_capenable;
 		enabled &= ~BRIDGE_IFCAPS_STRIP;
-		/* strip off mask bits and enable them again if allowed */
+		/* Strip off mask bits and enable them again if allowed */
 		enabled &= ~BRIDGE_IFCAPS_MASK;
 		enabled |= mask;
 		bridge_set_ifcap(sc, bif, enabled);
@@ -1282,7 +1294,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
 #endif
 			break;
 		}
-		/* reneable any interface capabilities */
+		/* Re-enable any interface capabilities */
 		bridge_set_ifcap(sc, bif, bif->bif_savedcaps);
 	}
 	bstp_destroy(&bif->bif_stp);	/* prepare to free */
@@ -1318,21 +1330,25 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 
 	ifs = ifunit(req->ifbr_ifsname);
 	if (ifs == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "No such interface",
+		    req->ifbr_ifsname));
 	if (ifs->if_ioctl == NULL)	/* must be supported */
-		return (EINVAL);
+		return (EXTERROR(EINVAL, "Interface must support ioctl(2)"));
 
 	/* If it's in the span list, it can't be a member. */
 	CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
 		if (ifs == bif->bif_ifp)
-			return (EBUSY);
+			return (EXTERROR(EBUSY,
+			    "Span interface cannot be a member"));
 
 	if (ifs->if_bridge) {
 		struct bridge_iflist *sbif = ifs->if_bridge;
 		if (sbif->bif_sc == sc)
-			return (EEXIST);
+			return (EXTERROR(EEXIST,
+			    "Interface is already a member of this bridge"));
 
-		return (EBUSY);
+		return (EXTERROR(EBUSY,
+		    "Interface is already a member of another bridge"));
 	}
 
 	switch (ifs->if_type) {
@@ -1342,7 +1358,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 		/* permitted interface types */
 		break;
 	default:
-		return (EINVAL);
+		return (EXTERROR(EINVAL, "Unsupported interface type"));
 	}
 
 #ifdef INET6
@@ -1394,11 +1410,15 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 		CK_STAILQ_FOREACH(ifa, &ifs->if_addrhead, ifa_link) {
 #ifdef INET
 			if (ifa->ifa_addr->sa_family == AF_INET)
-				return (EINVAL);
+				return (EXTERROR(EINVAL,
+				    "Member interface may not have "
+				    "an IPv4 address configured"));
 #endif
 #ifdef INET6
 			if (ifa->ifa_addr->sa_family == AF_INET6)
-				return (EINVAL);
+				return (EXTERROR(EINVAL,
+				    "Member interface may not have "
+				    "an IPv6 address configured"));
 #endif
 		}
 	}
@@ -1420,7 +1440,8 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 			    " new member %s\n", sc->sc_ifp->if_xname,
 			    ifr.ifr_mtu,
 			    ifs->if_xname);
-			return (EINVAL);
+			return (EXTERROR(EINVAL,
+			    "Failed to set MTU on new member"));
 		}
 	}
 
@@ -1482,7 +1503,7 @@ bridge_ioctl_del(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	bridge_delete_member(sc, bif, 0);
 
@@ -1498,7 +1519,7 @@ bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	bp = &bif->bif_stp;
 	req->ifbr_ifsflags = bif->bif_flags;
@@ -1541,12 +1562,12 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 	bp = &bif->bif_stp;
 
 	if (req->ifbr_ifsflags & IFBIF_SPAN)
 		/* SPAN is readonly */
-		return (EINVAL);
+		return (EXTERROR(EINVAL, "Span interface cannot be modified"));
 
 	NET_EPOCH_ENTER(et);
 
@@ -1555,7 +1576,8 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
 			error = bstp_enable(&bif->bif_stp);
 			if (error) {
 				NET_EPOCH_EXIT(et);
-				return (error);
+				return (EXTERROR(error,
+				    "Failed to enable STP"));
 			}
 		}
 	} else {
@@ -1724,7 +1746,7 @@ bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
 	bif = bridge_lookup_member(sc, req->ifba_ifsname);
 	if (bif == NULL) {
 		NET_EPOCH_EXIT(et);
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 	}
 
 	/* bridge_rtupdate() may acquire the lock. */
@@ -1858,7 +1880,7 @@ bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	return (bstp_set_port_priority(&bif->bif_stp, req->ifbr_priority));
 }
@@ -1871,7 +1893,7 @@ bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	return (bstp_set_path_cost(&bif->bif_stp, req->ifbr_path_cost));
 }
@@ -1884,7 +1906,7 @@ bridge_ioctl_sifmaxaddr(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	bif->bif_addrmax = req->ifbr_addrmax;
 	return (0);
@@ -1898,10 +1920,10 @@ bridge_ioctl_sifuntagged(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	if (req->ifbr_untagged > DOT1Q_VID_MAX)
-		return (EINVAL);
+		return (EXTERROR(EINVAL, "Invalid VLAN ID"));
 
 	if (req->ifbr_untagged != DOT1Q_VID_NULL)
 		bif->bif_flags |= IFBIF_VLANFILTER;
@@ -1917,12 +1939,12 @@ bridge_ioctl_sifvlanset(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->bv_ifname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	/* Reject invalid VIDs. */
 	if (BRVLAN_TEST(&req->bv_set, DOT1Q_VID_NULL) ||
 	    BRVLAN_TEST(&req->bv_set, DOT1Q_VID_RSVD_IMPL))
-		return (EINVAL);
+		return (EXTERROR(EINVAL, "Invalid VLAN ID in set"));
 
 	switch (req->bv_op) {
 		/* Replace the existing vlan set with the new set */
@@ -1942,7 +1964,8 @@ bridge_ioctl_sifvlanset(struct bridge_softc *sc, void *arg)
 
 		/* Invalid or unknown operation */
 	default:
-		return (EINVAL);
+		return (EXTERROR(EINVAL,
+		    "Unsupported BRDGSIFVLANSET operation"));
 	}
 
 	/*
@@ -1962,7 +1985,7 @@ bridge_ioctl_gifvlanset(struct bridge_softc *sc, void *arg)
 
 	bif = bridge_lookup_member(sc, req->bv_ifname);
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a bridge member"));
 
 	BIT_COPY(BRVLAN_SETSIZE, &bif->bif_vlan_set, &req->bv_set);
 	return (0);
@@ -1977,14 +2000,16 @@ bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
 
 	ifs = ifunit(req->ifbr_ifsname);
 	if (ifs == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "No such interface"));
 
 	CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
 		if (ifs == bif->bif_ifp)
-			return (EBUSY);
+			return (EXTERROR(EBUSY,
+			    "Interface is already a span port"));
 
 	if (ifs->if_bridge != NULL)
-		return (EBUSY);
+		return (EXTERROR(EEXIST,
+		    "Interface is already a bridge member"));
 
 	switch (ifs->if_type) {
 		case IFT_ETHER:
@@ -1992,7 +2017,7 @@ bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
 		case IFT_L2VLAN:
 			break;
 		default:
-			return (EINVAL);
+			return (EXTERROR(EINVAL, "Unsupported interface type"));
 	}
 
 	bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
@@ -2016,14 +2041,14 @@ bridge_ioctl_delspan(struct bridge_softc *sc, void *arg)
 
 	ifs = ifunit(req->ifbr_ifsname);
 	if (ifs == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "No such interface"));
 
 	CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
 		if (ifs == bif->bif_ifp)
 			break;
 
 	if (bif == NULL)
-		return (ENOENT);
+		return (EXTERROR(ENOENT, "Interface is not a span port"));
 
 	bridge_delete_span(sc, bif);
 
@@ -3244,10 +3269,11 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
 	BRIDGE_LOCK_OR_NET_EPOCH_ASSERT(sc);
 
 	/* Check the source address is valid and not multicast. */
-	if (ETHER_IS_MULTICAST(dst) ||
-	    (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
-	     dst[3] == 0 && dst[4] == 0 && dst[5] == 0) != 0)
-		return (EINVAL);
+	if (ETHER_IS_MULTICAST(dst))
+		return (EXTERROR(EINVAL, "Multicast address not permitted"));
+	if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
+	    dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
+		return (EXTERROR(EINVAL, "Zero address not permitted"));
 
 	/*
 	 * A route for this destination might already exist.  If so,
@@ -3266,13 +3292,14 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
 		if (sc->sc_brtcnt >= sc->sc_brtmax) {
 			sc->sc_brtexceeded++;
 			BRIDGE_RT_UNLOCK(sc);
-			return (ENOSPC);
+			return (EXTERROR(ENOSPC, "Address table is full"));
 		}
 		/* Check per interface address limits (if enabled) */
 		if (bif->bif_addrmax && bif->bif_addrcnt >= bif->bif_addrmax) {
 			bif->bif_addrexceeded++;
 			BRIDGE_RT_UNLOCK(sc);
-			return (ENOSPC);
+			return (EXTERROR(ENOSPC,
+			    "Interface address limit exceeded"));
 		}
 
 		/*
@@ -3283,7 +3310,8 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
 		brt = uma_zalloc(V_bridge_rtnode_zone, M_NOWAIT | M_ZERO);
 		if (brt == NULL) {
 			BRIDGE_RT_UNLOCK(sc);
-			return (ENOMEM);
+			return (EXTERROR(ENOMEM,
+			    "Cannot allocate address node"));
 		}
 		brt->brt_vnet = curvnet;
 
@@ -3631,7 +3659,7 @@ bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
 	do {
 		dir = bridge_rtnode_addr_cmp(brt->brt_addr, lbrt->brt_addr);
 		if (dir == 0 && brt->brt_vlan == lbrt->brt_vlan)
-			return (EEXIST);
+			return (EXTERROR(EEXIST, "Address already exists"));
 		if (dir > 0) {
 			CK_LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
 			goto out;
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
index cab94ac511a5..a8e1f56e132e 100644
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -18,6 +18,7 @@
 #define	EXTERR_CAT_FUSE		4
 #define	EXTERR_CAT_INOTIFY	5
 #define	EXTERR_CAT_GENIO	6
+#define	EXTERR_CAT_BRIDGE	7
 
 #endif