diff options
-rw-r--r-- | sbin/ifconfig/ifmedia.c | 32 | ||||
-rw-r--r-- | sys/net/ieee8023ad_lacp.c | 42 | ||||
-rw-r--r-- | sys/net/if.c | 1 | ||||
-rw-r--r-- | sys/net/if_media.c | 31 | ||||
-rw-r--r-- | sys/net/if_media.h | 108 | ||||
-rw-r--r-- | sys/sys/sockio.h | 1 |
6 files changed, 201 insertions, 14 deletions
diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c index 0b0daa3..eee3391 100644 --- a/sbin/ifconfig/ifmedia.c +++ b/sbin/ifconfig/ifmedia.c @@ -109,11 +109,17 @@ media_status(int s) { struct ifmediareq ifmr; int *media_list, i; + int xmedia = 1; (void) memset(&ifmr, 0, sizeof(ifmr)); (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { + /* + * Check if interface supports extended media types. + */ + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0) + xmedia = 0; + if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { /* * Interface doesn't support SIOC{G,S}IFMEDIA. */ @@ -130,8 +136,13 @@ media_status(int s) err(1, "malloc"); ifmr.ifm_ulist = media_list; - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) - err(1, "SIOCGIFMEDIA"); + if (xmedia) { + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFXMEDIA"); + } else { + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + } printf("\tmedia: "); print_media_word(ifmr.ifm_current, 1); @@ -194,6 +205,7 @@ ifmedia_getstate(int s) { static struct ifmediareq *ifmr = NULL; int *mwords; + int xmedia = 1; if (ifmr == NULL) { ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); @@ -213,7 +225,10 @@ ifmedia_getstate(int s) * the current media type and the top-level type. */ - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0) { + xmedia = 0; + } + if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) { err(1, "SIOCGIFMEDIA"); } @@ -225,8 +240,13 @@ ifmedia_getstate(int s) err(1, "malloc"); ifmr->ifm_ulist = mwords; - if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) - err(1, "SIOCGIFMEDIA"); + if (xmedia) { + if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0) + err(1, "SIOCGIFXMEDIA"); + } else { + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) + err(1, "SIOCGIFMEDIA"); + } } return ifmr; diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index c422c25..64aafb1 100644 --- a/sys/net/ieee8023ad_lacp.c +++ b/sys/net/ieee8023ad_lacp.c @@ -1066,12 +1066,16 @@ lacp_compose_key(struct lacp_port *lp) case IFM_100_T4: case IFM_100_VG: case IFM_100_T2: + case IFM_100_T: key = IFM_100_TX; break; case IFM_1000_SX: case IFM_1000_LX: case IFM_1000_CX: case IFM_1000_T: + case IFM_1000_KX: + case IFM_1000_SGMII: + case IFM_1000_CX_SGMII: key = IFM_1000_SX; break; case IFM_10G_LR: @@ -1081,15 +1085,53 @@ lacp_compose_key(struct lacp_port *lp) case IFM_10G_TWINAX_LONG: case IFM_10G_LRM: case IFM_10G_T: + case IFM_10G_KX4: + case IFM_10G_KR: + case IFM_10G_CR1: + case IFM_10G_ER: + case IFM_10G_SFI: key = IFM_10G_LR; break; + case IFM_20G_KR2: + key = IFM_20G_KR2; + break; + case IFM_2500_KX: + case IFM_2500_T: + key = IFM_2500_KX; + break; + case IFM_5000_T: + key = IFM_5000_T; + break; + case IFM_50G_PCIE: + case IFM_50G_CR2: + case IFM_50G_KR2: + key = IFM_50G_PCIE; + break; + case IFM_56G_R4: + key = IFM_56G_R4; + break; + case IFM_25G_PCIE: + case IFM_25G_CR: + case IFM_25G_KR: + case IFM_25G_SR: + key = IFM_25G_PCIE; + break; case IFM_40G_CR4: case IFM_40G_SR4: case IFM_40G_LR4: + case IFM_40G_XLPPI: + case IFM_40G_KR4: key = IFM_40G_CR4; break; + case IFM_100G_CR4: + case IFM_100G_SR4: + case IFM_100G_KR4: + case IFM_100G_LR4: + key = IFM_100G_CR4; + break; default: key = subtype; + break; } /* bit 5..14: (some bits of) if_index of lagg device */ key |= 0x7fe0 & ((sc->sc_ifp->if_index) << 5); diff --git a/sys/net/if.c b/sys/net/if.c index 9d56803..1dec451 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2582,6 +2582,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) case SIOCGIFPSRCADDR: case SIOCGIFPDSTADDR: case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: case SIOCGIFGENERIC: if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); diff --git a/sys/net/if_media.c b/sys/net/if_media.c index 810db3f..a76ec90 100644 --- a/sys/net/if_media.c +++ b/sys/net/if_media.c @@ -68,6 +68,7 @@ static struct ifmedia_entry *ifmedia_match(struct ifmedia *ifm, int flags, int mask); #ifdef IFMEDIA_DEBUG +#include <net/if_var.h> int ifmedia_debug = 0; SYSCTL_INT(_debug, OID_AUTO, ifmedia, CTLFLAG_RW, &ifmedia_debug, 0, "if_media debugging msgs"); @@ -193,6 +194,21 @@ ifmedia_set(ifm, target) } /* + * Given a media word, return one suitable for an application + * using the original encoding. + */ +static int +compat_media(int media) +{ + + if (IFM_TYPE(media) == IFM_ETHER && IFM_SUBTYPE(media) > IFM_OTHER) { + media &= ~(IFM_ETH_XTYPE|IFM_TMASK); + media |= IFM_OTHER; + } + return (media); +} + +/* * Device-independent media ioctl support function. */ int @@ -271,6 +287,7 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) * Get list of available media and current media on interface. */ case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: { struct ifmedia_entry *ep; int i; @@ -278,8 +295,13 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd) if (ifmr->ifm_count < 0) return (EINVAL); - ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ? - ifm->ifm_cur->ifm_media : IFM_NONE; + if (cmd == SIOCGIFMEDIA) { + ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ? + compat_media(ifm->ifm_cur->ifm_media) : IFM_NONE; + } else { + ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ? + ifm->ifm_cur->ifm_media : IFM_NONE; + } ifmr->ifm_mask = ifm->ifm_mask; ifmr->ifm_status = 0; (*ifm->ifm_status)(ifp, ifmr); @@ -354,8 +376,7 @@ ifmedia_baudrate(int mword) int i; for (i = 0; ifmedia_baudrate_descriptions[i].ifmb_word != 0; i++) { - if ((mword & (IFM_NMASK|IFM_TMASK)) == - ifmedia_baudrate_descriptions[i].ifmb_word) + if (IFM_TYPE_MATCH(mword, ifmedia_baudrate_descriptions[i].ifmb_word)) return (ifmedia_baudrate_descriptions[i].ifmb_baudrate); } @@ -461,7 +482,7 @@ ifmedia_printword(ifmw) printf("<unknown type>\n"); return; } - printf(desc->ifmt_string); + printf("%s", desc->ifmt_string); /* Any mode. */ for (desc = ttos->modes; desc && desc->ifmt_string != NULL; desc++) diff --git a/sys/net/if_media.h b/sys/net/if_media.h index 88384f3..8643995 100644 --- a/sys/net/if_media.h +++ b/sys/net/if_media.h @@ -118,7 +118,7 @@ uint64_t ifmedia_baudrate(int); * ---- ------- * 0-4 Media variant * 5-7 Media type - * 8-15 Type specific options + * 8-15 Type specific options (includes added variant bits on Ethernet) * 16-18 Mode (for multi-mode devices) * 19 RFU * 20-27 Shared (global) options @@ -127,8 +127,18 @@ uint64_t ifmedia_baudrate(int); /* * Ethernet + * In order to use more than 31 subtypes, Ethernet uses some of the option + * bits as part of the subtype field. See the options section below for + * relevant definitions */ #define IFM_ETHER 0x00000020 +#define IFM_ETHER_SUBTYPE(x) (((x) & IFM_TMASK) | \ + (((x) & (IFM_ETH_XTYPE >> IFM_ETH_XSHIFT)) << IFM_ETH_XSHIFT)) +#define IFM_X(x) IFM_ETHER_SUBTYPE(x) /* internal shorthand */ +#define IFM_ETHER_SUBTYPE_SET(x) (IFM_ETHER_SUBTYPE(x) | IFM_ETHER) +#define IFM_ETHER_SUBTYPE_GET(x) ((x) & (IFM_TMASK|IFM_ETH_XTYPE)) +#define IFM_ETHER_IS_EXTENDED(x) ((x) & IFM_ETH_XTYPE) + #define IFM_10_T 3 /* 10BaseT - RJ45 */ #define IFM_10_2 4 /* 10Base2 - Thinnet */ #define IFM_10_5 5 /* 10Base5 - AUI */ @@ -156,15 +166,49 @@ uint64_t ifmedia_baudrate(int); #define IFM_40G_CR4 27 /* 40GBase-CR4 */ #define IFM_40G_SR4 28 /* 40GBase-SR4 */ #define IFM_40G_LR4 29 /* 40GBase-LR4 */ +#define IFM_1000_KX 30 /* 1000Base-KX backplane */ +#define IFM_OTHER 31 /* Other: one of the following */ + +/* following types are not visible to old binaries using only IFM_TMASK */ +#define IFM_10G_KX4 IFM_X(32) /* 10GBase-KX4 backplane */ +#define IFM_10G_KR IFM_X(33) /* 10GBase-KR backplane */ +#define IFM_10G_CR1 IFM_X(34) /* 10GBase-CR1 Twinax splitter */ +#define IFM_20G_KR2 IFM_X(35) /* 20GBase-KR2 backplane */ +#define IFM_2500_KX IFM_X(36) /* 2500Base-KX backplane */ +#define IFM_2500_T IFM_X(37) /* 2500Base-T - RJ45 (NBaseT) */ +#define IFM_5000_T IFM_X(38) /* 5000Base-T - RJ45 (NBaseT) */ +#define IFM_50G_PCIE IFM_X(39) /* 50G Ethernet over PCIE */ +#define IFM_25G_PCIE IFM_X(40) /* 25G Ethernet over PCIE */ +#define IFM_1000_SGMII IFM_X(41) /* 1G media interface */ +#define IFM_10G_SFI IFM_X(42) /* 10G media interface */ +#define IFM_40G_XLPPI IFM_X(43) /* 40G media interface */ +#define IFM_1000_CX_SGMII IFM_X(44) /* 1000Base-CX-SGMII */ +#define IFM_40G_KR4 IFM_X(45) /* 40GBase-KR4 */ +#define IFM_10G_ER IFM_X(46) /* 10GBase-ER */ +#define IFM_100G_CR4 IFM_X(47) /* 100GBase-CR4 */ +#define IFM_100G_SR4 IFM_X(48) /* 100GBase-SR4 */ +#define IFM_100G_KR4 IFM_X(49) /* 100GBase-KR4 */ +#define IFM_100G_LR4 IFM_X(50) /* 100GBase-LR4 */ +#define IFM_56G_R4 IFM_X(51) /* 56GBase-R4 */ +#define IFM_100_T IFM_X(52) /* 100BaseT - RJ45 */ +#define IFM_25G_CR IFM_X(53) /* 25GBase-CR */ +#define IFM_25G_KR IFM_X(54) /* 25GBase-KR */ +#define IFM_25G_SR IFM_X(55) /* 25GBase-SR */ +#define IFM_50G_CR2 IFM_X(56) /* 50GBase-CR2 */ +#define IFM_50G_KR2 IFM_X(57) /* 50GBase-KR2 */ + /* * Please update ieee8023ad_lacp.c:lacp_compose_key() * after adding new Ethernet media types. */ -/* note 31 is the max! */ +/* Note IFM_X(511) is the max! */ +/* Ethernet option values; includes bits used for extended variant field */ #define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */ #define IFM_ETH_RXPAUSE 0x00000200 /* receive PAUSE frames */ #define IFM_ETH_TXPAUSE 0x00000400 /* transmit PAUSE frames */ +#define IFM_ETH_XTYPE 0x00007800 /* extended media variants */ +#define IFM_ETH_XSHIFT 6 /* shift XTYPE next to TMASK */ /* * Token ring @@ -307,7 +351,10 @@ uint64_t ifmedia_baudrate(int); * Macros to extract various bits of information from the media word. */ #define IFM_TYPE(x) ((x) & IFM_NMASK) -#define IFM_SUBTYPE(x) ((x) & IFM_TMASK) +#define IFM_SUBTYPE(x) \ + (IFM_TYPE(x) == IFM_ETHER ? IFM_ETHER_SUBTYPE_GET(x) : ((x) & IFM_TMASK)) +#define IFM_TYPE_MATCH(x,y) \ + (IFM_TYPE(x) == IFM_TYPE(y) && IFM_SUBTYPE(x) == IFM_SUBTYPE(y)) #define IFM_TYPE_OPTIONS(x) ((x) & IFM_OMASK) #define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT) #define IFM_OPTIONS(x) ((x) & (IFM_OMASK | IFM_GMASK)) @@ -372,6 +419,34 @@ struct ifmedia_description { { IFM_40G_CR4, "40Gbase-CR4" }, \ { IFM_40G_SR4, "40Gbase-SR4" }, \ { IFM_40G_LR4, "40Gbase-LR4" }, \ + { IFM_1000_KX, "1000Base-KX" }, \ + { IFM_OTHER, "Other" }, \ + { IFM_10G_KX4, "10GBase-KX4" }, \ + { IFM_10G_KR, "10GBase-KR" }, \ + { IFM_10G_CR1, "10GBase-CR1" }, \ + { IFM_20G_KR2, "20GBase-KR2" }, \ + { IFM_2500_KX, "2500Base-KX" }, \ + { IFM_2500_T, "2500Base-T" }, \ + { IFM_5000_T, "5000Base-T" }, \ + { IFM_50G_PCIE, "PCIExpress-50G" }, \ + { IFM_25G_PCIE, "PCIExpress-25G" }, \ + { IFM_1000_SGMII, "1000Base-SGMII" }, \ + { IFM_10G_SFI, "10GBase-SFI" }, \ + { IFM_40G_XLPPI, "40GBase-XLPPI" }, \ + { IFM_1000_CX_SGMII, "1000Base-CX-SGMII" }, \ + { IFM_40G_KR4, "40GBase-KR4" }, \ + { IFM_10G_ER, "10GBase-ER" }, \ + { IFM_100G_CR4, "100GBase-CR4" }, \ + { IFM_100G_SR4, "100GBase-SR4" }, \ + { IFM_100G_KR4, "100GBase-KR4" }, \ + { IFM_100G_LR4, "100GBase-LR4" }, \ + { IFM_56G_R4, "56GBase-R4" }, \ + { IFM_100_T, "100BaseT" }, \ + { IFM_25G_CR, "25GBase-CR" }, \ + { IFM_25G_KR, "25GBase-KR" }, \ + { IFM_25G_SR, "25GBase-SR" }, \ + { IFM_50G_CR2, "50GBase-CR2" }, \ + { IFM_50G_KR2, "50GBase-KR2" }, \ { 0, NULL }, \ } @@ -673,6 +748,33 @@ struct ifmedia_baudrate { { IFM_ETHER | IFM_40G_CR4, IF_Gbps(40ULL) }, \ { IFM_ETHER | IFM_40G_SR4, IF_Gbps(40ULL) }, \ { IFM_ETHER | IFM_40G_LR4, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_1000_KX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_10G_KX4, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_KR, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_10G_CR1, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_20G_KR2, IF_Gbps(20ULL) }, \ + { IFM_ETHER | IFM_2500_KX, IF_Mbps(2500) }, \ + { IFM_ETHER | IFM_2500_T, IF_Mbps(2500) }, \ + { IFM_ETHER | IFM_5000_T, IF_Mbps(5000) }, \ + { IFM_ETHER | IFM_50G_PCIE, IF_Gbps(50ULL) }, \ + { IFM_ETHER | IFM_25G_PCIE, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_1000_SGMII, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_10G_SFI, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_40G_XLPPI, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_1000_CX_SGMII, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_40G_KR4, IF_Gbps(40ULL) }, \ + { IFM_ETHER | IFM_10G_ER, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_100G_CR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_100G_SR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_100G_KR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_100G_LR4, IF_Gbps(100ULL) }, \ + { IFM_ETHER | IFM_56G_R4, IF_Gbps(56ULL) }, \ + { IFM_ETHER | IFM_100_T, IF_Mbps(100ULL) }, \ + { IFM_ETHER | IFM_25G_CR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_25G_KR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_25G_SR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_50G_CR2, IF_Gbps(50ULL) }, \ + { IFM_ETHER | IFM_50G_KR2, IF_Gbps(50ULL) }, \ \ { IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \ { IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \ diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h index 7b09acf..f04bb12 100644 --- a/sys/sys/sockio.h +++ b/sys/sys/sockio.h @@ -128,5 +128,6 @@ #define SIOCGIFGROUP _IOWR('i', 136, struct ifgroupreq) /* get ifgroups */ #define SIOCDIFGROUP _IOW('i', 137, struct ifgroupreq) /* delete ifgroup */ #define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) /* get members */ +#define SIOCGIFXMEDIA _IOWR('i', 139, struct ifmediareq) /* get net xmedia */ #endif /* !_SYS_SOCKIO_H_ */ |