diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 789b98fd7447..876b9b22ea56 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -1,3306 +1,3312 @@ .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .Dd November 08, 2023 .Dt IFCONFIG 8 .Os .Sh NAME .Nm ifconfig .Nd configure network interface parameters .Sh SYNOPSIS .Nm .Op Fl j Ar jail -.Op Fl kLmn +.Op Fl DkLmn .Op Fl f Ar type Ns Cm \&: Ns Ar format .Ar interface .Op Cm create .Oo .Ar address_family .Oo .Ar address .Op Ar dest_address .Oc .Oc .Op Ar parameters .Nm .Op Fl j Ar jail .Ar interface .Cm destroy .Nm .Op Fl j Ar jail .Fl a -.Op Fl dkLmuv +.Op Fl dDkLmuv .Op Fl f Ar type Ns Cm \&: Ns Ar format .Op Fl G Ar groupname .Op Fl g Ar groupname .Op Ar address_family .Nm .Fl C .Nm .Op Fl j Ar jail .Fl g Ar groupname .Nm .Op Fl j Ar jail .Fl l .Op Fl du .Op Fl g Ar groupname .Op Ar address_family .Nm .Op Fl j Ar jail .Op Fl dkLmuv .Op Fl f Ar type Ns Cm \&: Ns Ar format .Sh DESCRIPTION The .Nm utility is used to assign an address to a network interface and/or configure network interface parameters. The .Nm utility must be used at boot time to define the network address of each interface present on a machine; it may also be used at a later time to redefine an interface's address or other operating parameters. .Pp The following options are available: .Bl -tag -width indent .It Fl a Display information about all interfaces in the system. .Pp The .Fl a flag may be used instead of the .Ar interface argument. .It Fl C List all the interface cloners available on the system, with no additional information. Use of this flag is mutually exclusive with all other flags and commands. .It Fl d Display only the interfaces that are down. +.It Fl D +Include the driver name and unit number of the interface in the output. +This is normally the original name of the interface, +even if it has been renamed; it may differ from the original name +in some cases, such as +.Xr epair 4 . .It Fl f Xo .Ar type Ns Cm \&: Ns Ar format Ns .Op Cm \&, Ns Ar type Ns Cm \&: Ns Ar format Ar ... .Xc Control the output format of .Nm . The format is specified as a comma-separated list of .Ar type Ns Cm \&: Ns Ar format pairs .Po see the .Sx EXAMPLES section for more information .Pc . .Pp The output format can also be specified via the .Ev IFCONFIG_FORMAT environment variable. The .Fl f flag can be supplied multiple times. .Pp The .Ar type Ns s and their associated .Ar format strings are: .Pp .Bl -tag -width ether .It Cm addr Adjust the display of inet and inet6 addresses: .Pp .Bl -tag -width default -compact .It Cm default Default format, .Cm numeric .It Cm fqdn Fully qualified domain names .Pq FQDN .It Cm host Unqualified hostnames .It Cm numeric Numeric format .El .It Cm ether Adjust the display of link-level ethernet (MAC) addresses: .Pp .Bl -tag -width default -compact .It Cm colon Separate address segments with a colon .It Cm dash Separate address segments with a dash .It Cm dotted Dotted notation, for example: .Ql 5254.0015.4a3b .It Cm default Default format, .Cm colon .El .It Cm inet Adjust the display of inet address subnet masks: .Pp .Bl -tag -width default -compact .It Cm cidr CIDR notation, for example: .Ql 203.0.113.224/26 .It Cm default Default format, .Cm hex .It Cm dotted Dotted quad notation, for example: .Ql 255.255.255.192 .It Cm hex Hexadecimal format, for example: .Ql 0xffffffc0 .El .It Cm inet6 Adjust the display of inet6 address prefixes (subnet masks): .Pp .Bl -tag -width default -compact .It Cm cidr CIDR notation, for example: .Ql ::1/128 or .Ql fe80::1%lo0/64 .It Cm default Default format, .Cm numeric .It Cm numeric Integer format, for example: .Ql prefixlen 64 .El .El .It Fl G Ar groupname Exclude members of the specified .Ar groupname from the output. .Ar groupname . .Pp Only one option .Fl G should be specified as later override previous ones .Ar groupname may contain shell patterns in which case it should be quoted. .Pp Setting .Ar groupname to .Cm all selects all interfaces. .It Fl g Ar groupname Limit the output to the members of the specified .Ar groupname . .Pp If .Fl g is specified before other significant flags like, e.g., .Fl a , .Fl l , or .Fl C , then .Nm lists names of interfaces belonging to .Ar groupname . Any other flags and arguments are ignored in this case. .Pp Only one option .Fl g should be specified as later override previous ones .Ar groupname may contain shell patterns in which case it should be quoted. .Pp Setting .Ar groupname to .Cm all selects all interfaces. .It Fl j Ar jail Perform the actions inside the .Ar jail . .Pp The .Cm ifconfig will first attach to the .Ar jail (by jail id or jail name) before performing the effects. .Pp This allow network interfaces of .Ar jail to be configured even if the .Cm ifconfig binary is not available in .Ar jail . .It Fl k Print keying information for the .Ar interface , if available. .Pp For example, the values of 802.11 WEP keys and .Xr carp 4 passphrases will be printed, if accessible to the current user. .Pp This information is not printed by default, as it may be considered sensitive. .It Fl L Display address lifetime for IPv6 addresses as time offset string. .It Fl l List all available interfaces on the system, with no other additional information. .Pp If an .Ar address_family is specified, only interfaces of that type will be listed. .Pp If the .Ar address_family is set to .Cm ether , then .Fl l will exclude loopback interfaces from the list of Ethernet interfaces. This is a special case, because all the other synonyms of the .Cm link address family will include loopback interfaces in the list. .Pp Use of this flag is mutually exclusive with all other flags and commands, except for .Fl d , .Fl g , and .Fl u . .It Fl m Display the capability list and all of the supported media for the specified interface. .It Fl n Disable automatic loading of network interface drivers. .Pp By default if the network interface driver is not present in the kernel then .Nm will attempt to load it. .It Fl u Display only the interfaces that are up. .It Fl v Get more verbose status for an interface. .It Ar address For the inet family, the address is either a host name present in the host name data base, .Xr hosts 5 , or an IPv4 address expressed in the Internet standard .Dq dot notation . .Pp It is also possible to use the CIDR notation (also known as the slash notation) to include the netmask. That is, one can specify an address like .Li 192.168.0.1/16 . .Pp For the .Cm inet6 family, it is also possible to specify the prefix length using the slash notation, like .Li ::1/128 . See the .Cm prefixlen parameter below for more information. .Pp The link-level .Pq Cm link address is specified as a series of colon-separated hex digits. This can be used to, for example, set a new MAC address on an Ethernet interface, though the mechanism used is not Ethernet specific. .Pp Use the .Cm random keyword to set a randomly generated MAC address. A randomly-generated MAC address might be the same as one already in use in the network. Such duplications are extremely unlikely. .Pp If the interface is already up when the link-level address is modified, it will be briefly brought down and then brought back up again in order to ensure that the receive filter in the underlying Ethernet hardware is properly reprogrammed. .It Ar address_family Specify the address family which affects interpretation of the remaining parameters. Since an interface can receive transmissions in differing protocols with different naming schemes, specifying the address family is recommended. The address or protocol families currently supported are: .Bl -tag .It Cm ether Synonymous with .Cm link .Po with some exceptions, see .Fl l .Pc . .It Cm inet Default, if available. .It Cm inet6 .It Cm link Default, if .Cm inet is not available. .It Cm lladdr Synonymous with .Cm link . .El .It Ar dest_address Specify the address of the correspondent on the other end of a point to point link. .It Ar interface This parameter is a string of the form .Dq name unit , for example, .Dq Li em0 . .El .Pp The .Nm utility displays the current configuration for a network interface when no optional parameters are supplied. If a protocol family is specified, .Nm will report only the details specific to that protocol family. .Pp When no arguments are given, .Fl a is implied. .Pp Only the super-user may modify the configuration of a network interface. .Sh PARAMETERS The following .Ar parameter Ns s may be set with .Nm : .Bl -tag -width indent .It Cm add Another name for the .Cm alias parameter. Introduced for compatibility with .Bsx . .It Cm alias Establish an additional network address for this interface. This is sometimes useful when changing network numbers, and one wishes to accept packets addressed to the old interface. If the address is on the same subnet as the first network address for this interface, a non-conflicting netmask must be given. Usually .Li 0xffffffff is most appropriate. .It Fl alias Remove the network address specified. This would be used if you incorrectly specified an alias, or it was no longer needed. If you have incorrectly set an NS address having the side effect of specifying the host portion, removing all NS addresses will allow you to respecify the host portion. .It Cm anycast (Inet6 only.) Specify that the address configured is an anycast address. Based on the current specification, only routers may configure anycast addresses. Anycast address will not be used as source address of any of outgoing IPv6 packets. .It Cm arp Enable the use of the Address Resolution Protocol .Pq Xr arp 4 in mapping between network level addresses and link level addresses (default). This is currently implemented for mapping between Internet Protocol addresses and IEEE 802 48-bit MAC addresses (Ethernet addresses). .It Fl arp Disable the use of the Address Resolution Protocol .Pq Xr arp 4 . .It Cm staticarp If the Address Resolution Protocol is enabled, the host will only reply to requests for its addresses, and will never send any requests. .It Fl staticarp If the Address Resolution Protocol is enabled, the host will perform normally, sending out requests and listening for replies. .It Cm stickyarp Enable the so-called sticky ARP mode for the interface. If this option is enabled on the given interface, any resolved address is marked as a static one and never expires. This may be used to increase security of the network by preventing ARP spoofing or to reduce latency for high-performance Ethernet networks where the time needed for ARP resolution is too high. Please note that a similar feature is also provided for bridges. See the sticky option in the .Sx Bridge Interface Parameters section. Enabling this option may impact techniques which rely on ARP expiration/overwriting feature such as load-balancers or high-availabity solutions such as .Xr carp 4 . .It Fl stickyarp Disable the so-called sticky ARP mode for the interface (default). Resolved addresses will expire normally respecting the kernel ARP configuration. .It Cm broadcast (Inet only.) Specify the address to use to represent broadcasts to the network. The default broadcast address is the address with a host part of all 1's. .It Cm debug Enable driver dependent debugging code; usually, this turns on extra console error logging. .It Fl debug Disable driver dependent debugging code. .It Cm promisc Put interface into permanently promiscuous mode. .It Fl promisc Disable permanently promiscuous mode. .It Cm delete Another name for the .Fl alias parameter. .It Cm description Ar value , Cm descr Ar value Specify a description of the interface. This can be used to label interfaces in situations where they may otherwise be difficult to distinguish. .It Cm -description , Cm -descr Clear the interface description. .It Cm down Mark an interface .Dq down . When an interface is marked .Dq down , the system will not attempt to transmit messages through that interface. If possible, the interface will be reset to disable reception as well. This action does not automatically disable routes using the interface. .It Cm group Ar groupname Assign the interface to a .Dq group . The .Ar groupname may not be longer than 15 characters and must not end in a digit. Any interface can be in multiple groups. .Pp Cloned interfaces are members of their interface family group by default. For example, a VLAN interface such as .Em vlan10 is a member of the VLAN interface family group, .Em vlan . .It Cm -group Ar groupname Remove the interface from the given .Dq group . .It Cm eui64 (Inet6 only.) Fill interface index (lowermost 64bit of an IPv6 address) automatically. .It Cm fib Ar fib_number Specify interface FIB. A FIB .Ar fib_number is assigned to all frames or packets received on that interface. The FIB is not inherited, e.g., vlans or other sub-interfaces will use the default FIB (0) irrespective of the parent interface's FIB. The kernel needs to be tuned to support more than the default FIB using the .Va ROUTETABLES kernel configuration option, or the .Va net.fibs tunable. .It Cm tunnelfib Ar fib_number Specify tunnel FIB. A FIB .Ar fib_number is assigned to all packets encapsulated by tunnel interface, e.g., .Xr gif 4 , .Xr gre 4 and .Xr vxlan 4 . .It Cm maclabel Ar label If Mandatory Access Control support is enabled in the kernel, set the MAC label to .Ar label . .\" (see .\" .Xr maclabel 7 ) . .It Cm media Ar type If the driver supports the media selection system, set the media type of the interface to .Ar type . Some interfaces support the mutually exclusive use of one of several different physical media connectors. For example, a 10Mbit/s Ethernet interface might support the use of either AUI or twisted pair connectors. Setting the media type to .Cm 10base5/AUI would change the currently active connector to the AUI port. Setting it to .Cm 10baseT/UTP would activate twisted pair. Refer to the interfaces' driver specific documentation or man page for a complete list of the available types. .It Cm mediaopt Ar opts If the driver supports the media selection system, set the specified media options on the interface. The .Ar opts argument is a comma delimited list of options to apply to the interface. Refer to the interfaces' driver specific man page for a complete list of available options. .It Fl mediaopt Ar opts If the driver supports the media selection system, disable the specified media options on the interface. .It Cm mode Ar mode If the driver supports the media selection system, set the specified operating mode on the interface to .Ar mode . For IEEE 802.11 wireless interfaces that support multiple operating modes this directive is used to select between 802.11a .Pq Cm 11a , 802.11b .Pq Cm 11b , and 802.11g .Pq Cm 11g operating modes. .It Cm txrtlmt Set if the driver supports TX rate limiting. .It Cm inst Ar minst , Cm instance Ar minst Set the media instance to .Ar minst . This is useful for devices which have multiple physical layer interfaces .Pq PHYs . .It Cm name Ar name Set the interface name to .Ar name . .It Cm rxcsum , txcsum , rxcsum6 , txcsum6 If the driver supports user-configurable checksum offloading, enable receive (or transmit) checksum offloading on the interface. The feature can be turned on selectively per protocol family. Use .Cm rxcsum6 , txcsum6 for .Xr ip6 4 or .Cm rxcsum , txcsum otherwise. Some drivers may not be able to enable these flags independently of each other, so setting one may also set the other. The driver will offload as much checksum work as it can reliably support, the exact level of offloading varies between drivers. .It Fl rxcsum , txcsum , rxcsum6 , txcsum6 If the driver supports user-configurable checksum offloading, disable receive (or transmit) checksum offloading on the interface. The feature can be turned off selectively per protocol family. Use .Fl rxcsum6 , txcsum6 for .Xr ip6 4 or .Fl rxcsum , txcsum otherwise. These settings may not always be independent of each other. .It Cm tso If the driver supports .Xr tcp 4 segmentation offloading, enable TSO on the interface. Some drivers may not be able to support TSO for .Xr ip 4 and .Xr ip6 4 packets, so they may enable only one of them. .It Fl tso If the driver supports .Xr tcp 4 segmentation offloading, disable TSO on the interface. It will always disable TSO for .Xr ip 4 and .Xr ip6 4 . .It Cm tso6 , tso4 If the driver supports .Xr tcp 4 segmentation offloading for .Xr ip6 4 or .Xr ip 4 use one of these to selectively enabled it only for one protocol family. .It Fl tso6 , tso4 If the driver supports .Xr tcp 4 segmentation offloading for .Xr ip6 4 or .Xr ip 4 use one of these to selectively disable it only for one protocol family. .It Cm lro If the driver supports .Xr tcp 4 large receive offloading, enable LRO on the interface. .It Fl lro If the driver supports .Xr tcp 4 large receive offloading, disable LRO on the interface. .It Cm txtls Transmit TLS offload encrypts Transport Layer Security (TLS) records and segments the encrypted record into one or more .Xr tcp 4 segments over either .Xr ip 4 or .Xr ip6 4 . If the driver supports transmit TLS offload, enable transmit TLS offload on the interface. Some drivers may not be able to support transmit TLS offload for .Xr ip 4 and .Xr ip6 4 packets, so they may enable only one of them. .It Fl txtls If the driver supports transmit TLS offload, disable transmit TLS offload on the interface. It will always disable TLS for .Xr ip 4 and .Xr ip6 4 . .It Cm txtlsrtlmt Enable use of rate limiting (packet pacing) for TLS offload. .It Fl txtlsrtlmt Disable use of rate limiting for TLS offload. .It Cm mextpg If the driver supports extended multi-page .Xr mbuf 9 buffers, enable them on the interface. .It Fl mextpg If the driver supports extended multi-page .Xr mbuf 9 biffers, disable them on the interface. .It Cm wol , wol_ucast , wol_mcast , wol_magic Enable Wake On Lan (WOL) support, if available. WOL is a facility whereby a machine in a low power state may be woken in response to a received packet. There are three types of packets that may wake a system: ucast (directed solely to the machine's mac address), mcast (directed to a broadcast or multicast address), or magic .Po unicast or multicast frames with a .Dq magic contents .Pc . Not all devices support WOL, those that do indicate the mechanisms they support in their capabilities. .Cm wol is a synonym for enabling all available WOL mechanisms. To disable WOL use .Fl wol . .It Cm vlanmtu , vlanhwtag , vlanhwfilter , vlanhwcsum , vlanhwtso If the driver offers user-configurable VLAN support, enable reception of extended frames, tag processing in hardware, frame filtering in hardware, checksum offloading, or TSO on VLAN, respectively. Note that this must be configured on a physical interface associated with .Xr vlan 4 , not on a .Xr vlan 4 interface itself. .It Fl vlanmtu , vlanhwtag , vlanhwfilter , vlanhwcsum , vlanhwtso If the driver offers user-configurable VLAN support, disable reception of extended frames, tag processing in hardware, frame filtering in hardware, checksum offloading, or TSO on VLAN, respectively. .It Cm vxlanhwcsum , vxlanhwtso If the driver offers user-configurable VXLAN support, enable inner checksum offloading (receive and transmit) or TSO on VXLAN, respectively. Note that this must be configured on a physical interface associated with .Xr vxlan 4 , not on a .Xr vxlan 4 interface itself. The physical interface is either the interface specified as the vxlandev or the interface hosting the vxlanlocal address. The driver will offload as much checksum work and TSO as it can reliably support, the exact level of offloading may vary between drivers. .It Fl vxlanhwcsum , vxlanhwtso If the driver offers user-configurable VXLAN support, disable checksum offloading (receive and transmit) or TSO on VXLAN, respectively. .It Cm vnet Ar jail Move the interface to the .Xr jail 8 , specified by name or JID. If the jail has a virtual network stack, the interface will disappear from the current environment and become visible to the jail. .It Fl vnet Ar jail Reclaim the interface from the .Xr jail 8 , specified by name or JID. If the jail has a virtual network stack, the interface will disappear from the jail, and become visible to the current network environment. .It Cm polling Turn on .Xr polling 4 feature and disable interrupts on the interface, if driver supports this mode. .It Fl polling Turn off .Xr polling 4 feature and enable interrupt mode on the interface. .It Cm create Create the specified network pseudo-device. If the interface is given without a unit number, try to create a new device with an arbitrary unit number. If creation of an arbitrary device is successful, the new device name is printed to standard output unless the interface is renamed or destroyed in the same .Nm invocation. .It Cm destroy Destroy the specified network pseudo-device. .It Cm plumb Another name for the .Cm create parameter. Included for Solaris compatibility. .It Cm unplumb Another name for the .Cm destroy parameter. Included for Solaris compatibility. .It Cm metric Ar n Set the routing metric of the interface to .Ar n , default 0. The routing metric is used by the routing protocol .Pq Xr routed 8 . Higher metrics have the effect of making a route less favorable; metrics are counted as additional hops to the destination network or host. .It Cm mtu Ar n Set the maximum transmission unit of the interface to .Ar n , default is interface specific. The MTU is used to limit the size of packets that are transmitted on an interface. Not all interfaces support setting the MTU, and some interfaces have range restrictions. .It Cm netmask Ar mask .\" (Inet and ISO.) (Inet only.) Specify how much of the address to reserve for subdividing networks into sub-networks. The mask includes the network part of the local address and the subnet part, which is taken from the host field of the address. The mask can be specified as a single hexadecimal number with a leading .Ql 0x , with a dot-notation Internet address, or with a pseudo-network name listed in the network table .Xr networks 5 . The mask contains 1's for the bit positions in the 32-bit address which are to be used for the network and subnet parts, and 0's for the host part. The mask should contain at least the standard network portion, and the subnet field should be contiguous with the network portion. .Pp The netmask can also be specified in CIDR notation after the address. See the .Ar address option above for more information. .It Cm prefixlen Ar len (Inet6 only.) Specify that .Ar len bits are reserved for subdividing networks into sub-networks. The .Ar len must be integer, and for syntactical reason it must be between 0 to 128. It is almost always 64 under the current IPv6 assignment rule. If the parameter is omitted, 64 is used. .Pp The prefix can also be specified using the slash notation after the address. See the .Ar address option above for more information. .It Cm remove Another name for the .Fl alias parameter. Introduced for compatibility with .Bsx . .Sm off .It Cm link Op Cm 0 No - Cm 2 .Sm on Enable special processing of the link level of the interface. These three options are interface specific in actual effect, however, they are in general used to select special modes of operation. An example of this is to enable SLIP compression, or to select the connector type for some Ethernet cards. Refer to the man page for the specific driver for more information. .Sm off .It Fl link Op Cm 0 No - Cm 2 .Sm on Disable special processing at the link level with the specified interface. .It Cm monitor Put the interface in monitor mode. No packets are transmitted, and received packets are discarded after .Xr bpf 4 processing. .It Fl monitor Take the interface out of monitor mode. .It Cm pcp Ar priority_code_point Priority code point .Pq Dv PCP is an 3-bit field which refers to the IEEE 802.1p class of service and maps to the frame priority level. .It Fl pcp Stop tagging packets on the interface w/ the priority code point. .It Cm up Mark an interface .Dq up . This may be used to enable an interface after an .Dq Nm Cm down . It happens automatically when setting the first address on an interface. If the interface was reset when previously marked down, the hardware will be re-initialized. .El .Ss ICMPv6 Neighbor Discovery Protocol Parameters The following parameters are for ICMPv6 Neighbor Discovery Protocol. Note that the address family keyword .Dq Li inet6 is needed for them: .Bl -tag -width indent .It Cm accept_rtadv Set a flag to enable accepting ICMPv6 Router Advertisement messages. The .Xr sysctl 8 variable .Va net.inet6.ip6.accept_rtadv controls whether this flag is set by default or not. .It Cm -accept_rtadv Clear a flag .Cm accept_rtadv . .It Cm no_radr Set a flag to control whether routers from which the system accepts Router Advertisement messages will be added to the Default Router List or not. When the .Cm accept_rtadv flag is disabled, this flag has no effect. The .Xr sysctl 8 variable .Va net.inet6.ip6.no_radr controls whether this flag is set by default or not. .It Cm -no_radr Clear a flag .Cm no_radr . .It Cm auto_linklocal Set a flag to perform automatic link-local address configuration when the interface becomes available. The .Xr sysctl 8 variable .Va net.inet6.ip6.auto_linklocal controls whether this flag is set by default or not. .It Cm -auto_linklocal Clear a flag .Cm auto_linklocal . .It Cm defaultif Set the specified interface as the default route when there is no default router. .It Cm -defaultif Clear a flag .Cm defaultif . .It Cm ifdisabled Set a flag to disable all of IPv6 network communications on the specified interface. Note that if there are already configured IPv6 addresses on that interface, all of them are marked as .Dq tentative and DAD will be performed when this flag is cleared. .It Cm -ifdisabled Clear a flag .Cm ifdisabled . When this flag is cleared and .Cm auto_linklocal flag is enabled, automatic configuration of a link-local address is performed. .It Cm nud Set a flag to enable Neighbor Unreachability Detection. .It Cm -nud Clear a flag .Cm nud . .It Cm no_prefer_iface Set a flag to not honor rule 5 of source address selection in RFC 3484. In practice this means the address on the outgoing interface will not be preferred, effectively yielding the decision to the address selection policy table, configurable with .Xr ip6addrctl 8 . .It Cm -no_prefer_iface Clear a flag .Cm no_prefer_iface . .It Cm no_dad Set a flag to disable Duplicate Address Detection. .It Cm -no_dad Clear a flag .Cm no_dad . .El .Ss IPv6 Parameters The following parameters are specific for IPv6 addresses. Note that the address family keyword .Dq Li inet6 is needed for them: .Bl -tag -width indent .It Cm autoconf Set the IPv6 autoconfigured address bit. .It Fl autoconf Clear the IPv6 autoconfigured address bit. .It Cm deprecated Set the IPv6 deprecated address bit. .It Fl deprecated Clear the IPv6 deprecated address bit. .It Cm pltime Ar n Set preferred lifetime for the address. .It Cm prefer_source Set a flag to prefer address as a candidate of the source address for outgoing packets. .It Cm -prefer_source Clear a flag .Cm prefer_source . .It Cm vltime Ar n Set valid lifetime for the address. .El .Ss IEEE 802.11 Wireless Interfaces Cloning Parameters The following parameters are specific to cloning IEEE 802.11 wireless interfaces with the .Cm create request: .Bl -tag -width indent .It Cm wlandev Ar device Use .Ar device as the parent for the cloned device. .It Cm wlanmode Ar mode Specify the operating mode for this cloned device. .Ar mode is one of .Cm sta , .Cm ahdemo (or .Cm adhoc-demo ) , .Cm ibss (or .Cm adhoc ) , .Cm ap (or .Cm hostap ) , .Cm wds , .Cm tdma , .Cm mesh , and .Cm monitor . The operating mode of a cloned interface cannot be changed. The .Cm tdma mode is actually implemented as an .Cm adhoc-demo interface with special properties. .It Cm wlanbssid Ar bssid The 802.11 mac address to use for the bssid. This must be specified at create time for a legacy .Cm wds device. .It Cm wlanaddr Ar address The local mac address. If this is not specified then a mac address will automatically be assigned to the cloned device. Typically this address is the same as the address of the parent device but if the .Cm bssid parameter is specified then the driver will craft a unique address for the device (if supported). .It Cm wdslegacy Mark a .Cm wds device as operating in .Dq legacy mode . Legacy .Cm wds devices have a fixed peer relationship and do not, for example, roam if their peer stops communicating. For completeness a Dynamic WDS (DWDS) interface may marked as .Fl wdslegacy . .It Cm bssid Request a unique local mac address for the cloned device. This is only possible if the device supports multiple mac addresses. To force use of the parent's mac address use .Fl bssid . .It Cm beacons Mark the cloned interface as depending on hardware support to track received beacons. To have beacons tracked in software use .Fl beacons . For .Cm hostap mode .Fl beacons can also be used to indicate no beacons should be transmitted; this can be useful when creating a WDS configuration but .Cm wds interfaces can only be created as companions to an access point. .El .Ss Cloned IEEE 802.11 Wireless Interface Parameters The following parameters are specific to IEEE 802.11 wireless interfaces cloned with a .Cm create operation: .Bl -tag -width indent .It Cm ampdu Enable sending and receiving AMPDU frames when using 802.11n (default). The 802.11n specification states a compliant station must be capable of receiving AMPDU frames but transmission is optional. Use .Fl ampdu to disable all use of AMPDU with 802.11n. For testing and/or to work around interoperability problems one can use .Cm ampdutx and .Cm ampdurx to control use of AMPDU in one direction. .It Cm ampdudensity Ar density Set the AMPDU density parameter used when operating with 802.11n. This parameter controls the inter-packet gap for AMPDU frames. The sending device normally controls this setting but a receiving station may request wider gaps. Legal values for .Ar density are 0, .25, .5, 1, 2, 4, 8, and 16 (microseconds). A value of .Cm - is treated the same as 0. .It Cm ampdulimit Ar limit Set the limit on packet size for receiving AMPDU frames when operating with 802.11n. Legal values for .Ar limit are 8192, 16384, 32768, and 65536 but one can also specify just the unique prefix: 8, 16, 32, 64. Note the sender may limit the size of AMPDU frames to be less than the maximum specified by the receiving station. .It Cm amsdu Enable sending and receiving AMSDU frames when using 802.11n. By default AMSDU is received but not transmitted. Use .Fl amsdu to disable all use of AMSDU with 802.11n. For testing and/or to work around interoperability problems one can use .Cm amsdutx and .Cm amsdurx to control use of AMSDU in one direction. .It Cm amsdulimit Ar limit Set the limit on packet size for sending and receiving AMSDU frames when operating with 802.11n. Legal values for .Ar limit are 7935 and 3839 (bytes). Note the sender may limit the size of AMSDU frames to be less than the maximum specified by the receiving station. Note also that devices are not required to support the 7935 limit, only 3839 is required by the specification and the larger value may require more memory to be dedicated to support functionality that is rarely used. .It Cm apbridge When operating as an access point, pass packets between wireless clients directly (default). To instead let them pass up through the system and be forwarded using some other mechanism, use .Fl apbridge . Disabling the internal bridging is useful when traffic is to be processed with packet filtering. .It Cm authmode Ar mode Set the desired authentication mode in infrastructure mode. Not all adapters support all modes. The set of valid modes is .Cm none , open , shared (shared key), .Cm 8021x (IEEE 802.1x), and .Cm wpa (IEEE WPA/WPA2/802.11i). The .Cm 8021x and .Cm wpa modes are only useful when using an authentication service (a supplicant for client operation or an authenticator when operating as an access point). Modes are case insensitive. .It Cm bgscan Enable background scanning when operating as a station. Background scanning is a technique whereby a station associated to an access point will temporarily leave the channel to scan for neighboring stations. This allows a station to maintain a cache of nearby access points so that roaming between access points can be done without a lengthy scan operation. Background scanning is done only when a station is not busy and any outbound traffic will cancel a scan operation. Background scanning should never cause packets to be lost though there may be some small latency if outbound traffic interrupts a scan operation. By default background scanning is enabled if the device is capable. To disable background scanning, use .Fl bgscan . Background scanning is controlled by the .Cm bgscanidle and .Cm bgscanintvl parameters. Background scanning must be enabled for roaming; this is an artifact of the current implementation and may not be required in the future. .It Cm bgscanidle Ar idletime Set the minimum time a station must be idle (not transmitting or receiving frames) before a background scan is initiated. The .Ar idletime parameter is specified in milliseconds. By default a station must be idle at least 250 milliseconds before a background scan is initiated. The idle time may not be set to less than 100 milliseconds. .It Cm bgscanintvl Ar interval Set the interval at which background scanning is attempted. The .Ar interval parameter is specified in seconds. By default a background scan is considered every 300 seconds (5 minutes). The .Ar interval may not be set to less than 15 seconds. .It Cm bintval Ar interval Set the interval at which beacon frames are sent when operating in ad-hoc or ap mode. The .Ar interval parameter is specified in TU's (1024 usecs). By default beacon frames are transmitted every 100 TU's. .It Cm bmissthreshold Ar count Set the number of consecutive missed beacons at which the station will attempt to roam (i.e., search for a new access point). The .Ar count parameter must be in the range 1 to 255; though the upper bound may be reduced according to device capabilities. The default threshold is 7 consecutive missed beacons; but this may be overridden by the device driver. Another name for the .Cm bmissthreshold parameter is .Cm bmiss . .It Cm bssid Ar address Specify the MAC address of the access point to use when operating as a station in a BSS network. This overrides any automatic selection done by the system. To disable a previously selected access point, supply .Cm any , none , or .Cm - for the address. This option is useful when more than one access point uses the same SSID. Another name for the .Cm bssid parameter is .Cm ap . .It Cm burst Enable packet bursting. Packet bursting is a transmission technique whereby the wireless medium is acquired once to send multiple frames and the interframe spacing is reduced. This technique can significantly increase throughput by reducing transmission overhead. Packet bursting is supported by the 802.11e QoS specification and some devices that do not support QoS may still be capable. By default packet bursting is enabled if a device is capable of doing it. To disable packet bursting, use .Fl burst . .It Cm chanlist Ar channels Set the desired channels to use when scanning for access points, neighbors in an IBSS network, or looking for unoccupied channels when operating as an access point. The set of channels is specified as a comma-separated list with each element in the list representing either a single channel number or a range of the form .Dq Li a-b . Channel numbers must be in the range 1 to 255 and be permissible according to the operating characteristics of the device. .It Cm channel Ar number Set a single desired channel. Channels range from 1 to 255, but the exact selection available depends on the region your adaptor was manufactured for. Setting the channel to .Cm any , or .Dq Cm - will clear any desired channel and, if the device is marked up, force a scan for a channel to operate on. Alternatively the frequency, in megahertz, may be specified instead of the channel number. .Pp When there are several ways to use a channel the channel number/frequency may be appended with attributes to clarify. For example, if a device is capable of operating on channel 6 with 802.11n and 802.11g then one can specify that g-only use should be used by specifying .Cm 6:g . Similarly the channel width can be specified by appending it with .Dq Cm \&/ ; e.g., .Cm 6/40 specifies a 40MHz wide channel. These attributes can be combined as in: .Cm 6:ht/40 . .Pp The full set of flags specified following a .Dq Cm \&: are: .Pp .Bl -tag -compact .It Cm a 802.11a .It Cm b 802.11b .It Cm d Atheros Dynamic Turbo mode .It Cm g 802.11g .It Cm h Same as .Cm n .It Cm n 802.11n aka HT .It Cm s Atheros Static Turbo mode .It Cm t Atheros Dynamic Turbo mode, or appended to .Cm st and .Cm dt .El .Pp The full set of channel widths following a .Cm \&/ are: .Pp .Bl -tag -compact .It Cm 5 5MHz aka quarter-rate channel .It Cm 10 10MHz aka half-rate channel .It Cm 20 20MHz mostly for use in specifying .Cm ht20 .It Cm 40 40MHz mostly for use in specifying .Cm ht40 .El .Pp In addition, a 40MHz HT channel specification may include the location of the extension channel by appending .Dq Cm \&+ or .Dq Cm \&- for above and below, respectively; e.g., .Cm 2437:ht/40+ specifies 40MHz wide HT operation with the center channel at frequency 2437 and the extension channel above. .It Cm country Ar name Set the country code to use in calculating the regulatory constraints for operation. In particular the set of available channels, how the wireless device will operation on the channels, and the maximum transmit power that can be used on a channel are defined by this setting. Country/Region codes are specified as a 2-character abbreviation defined by ISO 3166 or using a longer, but possibly ambiguous, spelling; e.g., "ES" and "Spain". The set of country codes are taken from .Pa /etc/regdomain.xml and can also be viewed with the .Cm list countries request. Note that not all devices support changing the country code from a default setting; typically stored in EEPROM. See also .Cm regdomain , .Cm indoor , .Cm outdoor , and .Cm anywhere . .It Cm dfs Enable Dynamic Frequency Selection (DFS) as specified in 802.11h. DFS embodies several facilities including detection of overlapping radar signals, dynamic transmit power control, and channel selection according to a least-congested criteria. DFS support is mandatory for some 5GHz frequencies in certain locales (e.g., ETSI). By default DFS is enabled according to the regulatory definitions specified in .Pa /etc/regdomain.xml and the current country code, regdomain, and channel. Note the underlying device (and driver) must support radar detection for full DFS support to work. To be fully compliant with the local regulatory agency frequencies that require DFS should not be used unless it is fully supported. Use .Fl dfs to disable this functionality for testing. .It Cm dotd Enable support for the 802.11d specification (default). When this support is enabled in station mode, beacon frames that advertise a country code different than the currently configured country code will cause an event to be dispatched to user applications. This event can be used by the station to adopt that country code and operate according to the associated regulatory constraints. When operating as an access point with 802.11d enabled the beacon and probe response frames transmitted will advertise the current regulatory domain settings. To disable 802.11d use .Fl dotd . .It Cm doth Enable 802.11h support including spectrum management. When 802.11h is enabled beacon and probe response frames will have the SpectrumMgt bit set in the capabilities field and country and power constraint information elements will be present. 802.11h support also includes handling Channel Switch Announcements (CSA) which are a mechanism to coordinate channel changes by an access point. By default 802.11h is enabled if the device is capable. To disable 802.11h use .Fl doth . .It Cm deftxkey Ar index Set the default key to use for transmission. Typically this is only set when using WEP encryption. Note that you must set a default transmit key for the system to know which key to use in encrypting outbound traffic. The .Cm weptxkey is an alias for this request; it is provided for backwards compatibility. .It Cm dtimperiod Ar period Set the DTIM period for transmitting buffered multicast data frames when operating in ap mode. The .Ar period specifies the number of beacon intervals between DTIM and must be in the range 1 to 15. By default DTIM is 1 (i.e., DTIM occurs at each beacon). .It Cm quiet Enable the use of quiet IE. Hostap will use this to silence other stations to reduce interference for radar detection when operating on 5GHz frequency and doth support is enabled. Use .Fl quiet to disable this functionality. .It Cm quiet_period Ar period Set the QUIET .Ar period to the number of beacon intervals between the start of regularly scheduled quiet intervals defined by Quiet element. .It Cm quiet_count Ar count Set the QUIET .Ar count to the number of TBTTs until the beacon interval during which the next quiet interval shall start. A value of 1 indicates the quiet interval will start during the beacon interval starting at the next TBTT. A value 0 is reserved. .It Cm quiet_offset Ar offset Set the QUIET .Ar offset to the offset of the start of the quiet interval from the TBTT specified by the Quiet count, expressed in TUs. The value of the .Ar offset shall be less than one beacon interval. .It Cm quiet_duration Ar dur Set the QUIET .Ar dur to the duration of the Quiet interval, expressed in TUs. The value should be less than beacon interval. .It Cm dturbo Enable the use of Atheros Dynamic Turbo mode when communicating with another Dynamic Turbo-capable station. Dynamic Turbo mode is an Atheros-specific mechanism by which stations switch between normal 802.11 operation and a .Dq boosted mode in which a 40MHz wide channel is used for communication. Stations using Dynamic Turbo mode operate boosted only when the channel is free of non-dturbo stations; when a non-dturbo station is identified on the channel all stations will automatically drop back to normal operation. By default, Dynamic Turbo mode is not enabled, even if the device is capable. Note that turbo mode (dynamic or static) is only allowed on some channels depending on the regulatory constraints; use the .Cm list chan command to identify the channels where turbo mode may be used. To disable Dynamic Turbo mode use .Fl dturbo . .It Cm dwds Enable Dynamic WDS (DWDS) support. DWDS is a facility by which 4-address traffic can be carried between stations operating in infrastructure mode. A station first associates to an access point and authenticates using normal procedures (e.g., WPA). Then 4-address frames are passed to carry traffic for stations operating on either side of the wireless link. DWDS extends the normal WDS mechanism by leveraging existing security protocols and eliminating static binding. .Pp When DWDS is enabled on an access point 4-address frames received from an authorized station will generate a .Dq DWDS discovery event to user applications. This event should be used to create a WDS interface that is bound to the remote station (and usually plumbed into a bridge). Once the WDS interface is up and running 4-address traffic then logically flows through that interface. .Pp When DWDS is enabled on a station, traffic with a destination address different from the peer station are encapsulated in a 4-address frame and transmitted to the peer. All 4-address traffic uses the security information of the stations (e.g., cryptographic keys). A station is associated using 802.11n facilities may transport 4-address traffic using these same mechanisms; this depends on available resources and capabilities of the device. The DWDS implementation guards against layer 2 routing loops of multicast traffic. .It Cm ff Enable the use of Atheros Fast Frames when communicating with another Fast Frames-capable station. Fast Frames are an encapsulation technique by which two 802.3 frames are transmitted in a single 802.11 frame. This can noticeably improve throughput but requires that the receiving station understand how to decapsulate the frame. Fast frame use is negotiated using the Atheros 802.11 vendor-specific protocol extension so enabling use is safe when communicating with non-Atheros devices. By default, use of fast frames is enabled if the device is capable. To explicitly disable fast frames, use .Fl ff . .It Cm fragthreshold Ar length Set the threshold for which transmitted frames are broken into fragments. The .Ar length argument is the frame size in bytes and must be in the range 256 to 2346. Setting .Ar length to .Li 2346 , .Cm any , or .Cm - disables transmit fragmentation. Not all adapters honor the fragmentation threshold. .It Cm hidessid When operating as an access point, do not broadcast the SSID in beacon frames or respond to probe request frames unless they are directed to the ap (i.e., they include the ap's SSID). By default, the SSID is included in beacon frames and undirected probe request frames are answered. To re-enable the broadcast of the SSID etc., use .Fl hidessid . .It Cm ht Enable use of High Throughput (HT) when using 802.11n (default). The 802.11n specification includes mechanisms for operation on 20MHz and 40MHz wide channels using different signalling mechanisms than specified in 802.11b, 802.11g, and 802.11a. Stations negotiate use of these facilities, termed HT20 and HT40, when they associate. To disable all use of 802.11n use .Fl ht . To disable use of HT20 (e.g., to force only HT40 use) use .Fl ht20 . To disable use of HT40 use .Fl ht40 . .Pp HT configuration is used to .Dq auto promote operation when several choices are available. For example, if a station associates to an 11n-capable access point it controls whether the station uses legacy operation, HT20, or HT40. When an 11n-capable device is setup as an access point and Auto Channel Selection is used to locate a channel to operate on, HT configuration controls whether legacy, HT20, or HT40 operation is setup on the selected channel. If a fixed channel is specified for a station then HT configuration can be given as part of the channel specification; e.g., 6:ht/20 to setup HT20 operation on channel 6. .It Cm htcompat Enable use of compatibility support for pre-802.11n devices (default). The 802.11n protocol specification went through several incompatible iterations. Some vendors implemented 11n support to older specifications that will not interoperate with a purely 11n-compliant station. In particular the information elements included in management frames for old devices are different. When compatibility support is enabled both standard and compatible data will be provided. Stations that associate using the compatibility mechanisms are flagged in .Cm list sta . To disable compatibility support use .Fl htcompat . .It Cm htprotmode Ar technique For interfaces operating in 802.11n, use the specified .Ar technique for protecting HT frames in a mixed legacy/HT network. The set of valid techniques is .Cm off , and .Cm rts (RTS/CTS, default). Technique names are case insensitive. .It Cm inact Enable inactivity processing for stations associated to an access point (default). When operating as an access point the 802.11 layer monitors the activity of each associated station. When a station is inactive for 5 minutes it will send several .Dq probe frames to see if the station is still present. If no response is received then the station is deauthenticated. Applications that prefer to handle this work can disable this facility by using .Fl inact . .It Cm indoor Set the location to use in calculating regulatory constraints. The location is also advertised in beacon and probe response frames when 802.11d is enabled with .Cm dotd . See also .Cm outdoor , .Cm anywhere , .Cm country , and .Cm regdomain . .It Cm list active Display the list of channels available for use taking into account any restrictions set with the .Cm chanlist directive. See the description of .Cm list chan for more information. .It Cm list caps Display the adaptor's capabilities, including the operating modes supported. .It Cm list chan Display the list of channels available for use. Channels are shown with their IEEE channel number, equivalent frequency, and usage modes. Channels identified as .Ql 11g are also usable in .Ql 11b mode. Channels identified as .Ql 11a Turbo may be used only for Atheros' Static Turbo mode (specified with . Cm mediaopt turbo ) . Channels marked with a .Ql * have a regulatory constraint that they be passively scanned. This means a station is not permitted to transmit on the channel until it identifies the channel is being used for 802.11 communication; typically by hearing a beacon frame from an access point operating on the channel. .Cm list freq is another way of requesting this information. By default a compacted list of channels is displayed; if the .Fl v option is specified then all channels are shown. .It Cm list countries Display the set of country codes and regulatory domains that can be used in regulatory configuration. .It Cm list mac Display the current MAC Access Control List state. Each address is prefixed with a character that indicates the current policy applied to it: .Ql + indicates the address is allowed access, .Ql - indicates the address is denied access, .Ql * indicates the address is present but the current policy open (so the ACL is not consulted). .It Cm list mesh Displays the mesh routing table, used for forwarding packets on a mesh network. .It Cm list regdomain Display the current regulatory settings including the available channels and transmit power caps. .It Cm list roam Display the parameters that govern roaming operation. .It Cm list txparam Display the parameters that govern transmit operation. .It Cm list txpower Display the transmit power caps for each channel. .It Cm list scan Display the access points and/or ad-hoc neighbors located in the vicinity. This information may be updated automatically by the adapter with a .Cm scan request or through background scanning. Depending on the capabilities of the stations the following flags (capability codes) can be included in the output: .Bl -tag -width 3n .It Li A Channel agility. .It Li B PBCC modulation. .It Li C Poll request capability. .It Li D DSSS/OFDM capability. .It Li E Extended Service Set (ESS). Indicates that the station is part of an infrastructure network rather than an IBSS/ad-hoc network. .It Li I Independent Basic Service Set (IBSS). Indicates that the station is part of an ad-hoc network rather than an ESS network. .It Li P Privacy capability. The station requires authentication and encryption for all data frames exchanged within the BSS using cryptographic means such as WEP, TKIP, or AES-CCMP. .It Li R Robust Secure Network (RSN). .It Li S Short Preamble. Indicates that the network is using short preambles, defined in 802.11b High Rate/DSSS PHY, and utilizes a 56 bit sync field rather than the 128 bit field used in long preamble mode. Short preambles are used to optionally improve throughput performance with 802.11g and 802.11b. .It Li c Pollable capability. .It Li s Short slot time capability. Indicates that the 802.11g network is using a short slot time because there are no legacy (802.11b) stations present. .El .Pp By default interesting information elements captured from the neighboring stations are displayed at the end of each row. Possible elements include: .Cm WME (station supports WME), .Cm WPA (station supports WPA), .Cm WPS (station supports WPS), .Cm RSN (station supports 802.11i/RSN), .Cm HTCAP (station supports 802.11n/HT communication), .Cm ATH (station supports Atheros protocol extensions), .Cm VEN (station supports unknown vendor-specific extensions). If the .Fl v flag is used all the information elements and their contents will be shown. Specifying the .Fl v flag also enables display of long SSIDs. The .Cm list ap command is another way of requesting this information. .It Cm list sta When operating as an access point display the stations that are currently associated. When operating in ad-hoc mode display stations identified as neighbors in the IBSS. When operating in mesh mode display stations identified as neighbors in the MBSS. When operating in station mode display the access point. Capabilities advertised by the stations are described under the .Cm scan request. The following flags can be included in the output: .Bl -tag -width 3n .It Li A Authorized. Indicates that the station is permitted to send/receive data frames. .It Li E Extended Rate Phy (ERP). Indicates that the station is operating in an 802.11g network using extended transmit rates. .It Li H High Throughput (HT). Indicates that the station is using HT transmit rates. If a .Sq Li + follows immediately after then the station associated using deprecated mechanisms supported only when .Cm htcompat is enabled. .It Li P Power Save. Indicates that the station is operating in power save mode. .It Li Q Quality of Service (QoS). Indicates that the station is using QoS encapsulation for data frame. QoS encapsulation is enabled only when WME mode is enabled. .It Li S Short GI in HT 40MHz mode enabled. If a .Sq Li + follows immediately after then short GI in HT 20MHz mode is enabled as well. .It Li T Transitional Security Network (TSN). Indicates that the station associated using TSN; see also .Cm tsn below. .It Li W Wi-Fi Protected Setup (WPS). Indicates that the station associated using WPS. .It Li s Short GI in HT 20MHz mode enabled. .El .Pp By default information elements received from associated stations are displayed in a short form; the .Fl v flag causes this information to be displayed symbolically. .It Cm list wme Display the current channel parameters to use when operating in WME mode. If the .Fl v option is specified then both channel and BSS parameters are displayed for each AC (first channel, then BSS). When WME mode is enabled for an adaptor this information will be displayed with the regular status; this command is mostly useful for examining parameters when WME mode is disabled. See the description of the .Cm wme directive for information on the various parameters. .It Cm maxretry Ar count Set the maximum number of tries to use in sending unicast frames. The default setting is 6 but drivers may override this with a value they choose. .It Cm mcastrate Ar rate Set the rate for transmitting multicast/broadcast frames. Rates are specified as megabits/second in decimal; e.g.,\& 5.5 for 5.5 Mb/s. This rate should be valid for the current operating conditions; if an invalid rate is specified drivers are free to chose an appropriate rate. .It Cm mgtrate Ar rate Set the rate for transmitting management and/or control frames. Rates are specified as megabits/second in decimal; e.g.,\& 5.5 for 5.5 Mb/s. .It Cm outdoor Set the location to use in calculating regulatory constraints. The location is also advertised in beacon and probe response frames when 802.11d is enabled with .Cm dotd . See also .Cm anywhere , .Cm country , .Cm indoor , and .Cm regdomain . .It Cm powersave Enable powersave operation. When operating as a client, the station will conserve power by periodically turning off the radio and listening for messages from the access point telling it there are packets waiting. The station must then retrieve the packets. Not all devices support power save operation as a client. The 802.11 specification requires that all access points support power save but some drivers do not. Use .Fl powersave to disable powersave operation when operating as a client. .It Cm powersavesleep Ar sleep Set the desired max powersave sleep time in TU's (1024 usecs). By default the max powersave sleep time is 100 TU's. .It Cm protmode Ar technique For interfaces operating in 802.11g, use the specified .Ar technique for protecting OFDM frames in a mixed 11b/11g network. The set of valid techniques is .Cm off , cts (CTS to self), and .Cm rtscts (RTS/CTS). Technique names are case insensitive. Not all devices support .Cm cts as a protection technique. .It Cm pureg When operating as an access point in 802.11g mode allow only 11g-capable stations to associate (11b-only stations are not permitted to associate). To allow both 11g and 11b-only stations to associate, use .Fl pureg . .It Cm puren When operating as an access point in 802.11n mode allow only HT-capable stations to associate (legacy stations are not permitted to associate). To allow both HT and legacy stations to associate, use .Fl puren . .It Cm regdomain Ar sku Set the regulatory domain to use in calculating the regulatory constraints for operation. In particular the set of available channels, how the wireless device will operation on the channels, and the maximum transmit power that can be used on a channel are defined by this setting. Regdomain codes (SKU's) are taken from .Pa /etc/regdomain.xml and can also be viewed with the .Cm list countries request. Note that not all devices support changing the regdomain from a default setting; typically stored in EEPROM. See also .Cm country , .Cm indoor , .Cm outdoor , and .Cm anywhere . .It Cm rifs Enable use of Reduced InterFrame Spacing (RIFS) when operating in 802.11n on an HT channel. Note that RIFS must be supported by both the station and access point for it to be used. To disable RIFS use .Fl rifs . .It Cm roam:rate Ar rate Set the threshold for controlling roaming when operating in a BSS. The .Ar rate parameter specifies the transmit rate in megabits at which roaming should be considered. If the current transmit rate drops below this setting and background scanning is enabled, then the system will check if a more desirable access point is available and switch over to it. The current scan cache contents are used if they are considered valid according to the .Cm scanvalid parameter; otherwise a background scan operation is triggered before any selection occurs. Each channel type has a separate rate threshold; the default values are: 12 Mb/s (11a), 2 Mb/s (11b), 2 Mb/s (11g), MCS 1 (11na, 11ng). .It Cm roam:rssi Ar rssi Set the threshold for controlling roaming when operating in a BSS. The .Ar rssi parameter specifies the receive signal strength in dBm units at which roaming should be considered. If the current rssi drops below this setting and background scanning is enabled, then the system will check if a more desirable access point is available and switch over to it. The current scan cache contents are used if they are considered valid according to the .Cm scanvalid parameter; otherwise a background scan operation is triggered before any selection occurs. Each channel type has a separate rssi threshold; the default values are all 7 dBm. .It Cm roaming Ar mode When operating as a station, control how the system will behave when communication with the current access point is broken. The .Ar mode argument may be one of .Cm device (leave it to the hardware device to decide), .Cm auto (handle either in the device or the operating system\[em]as appropriate), .Cm manual (do nothing until explicitly instructed). By default, the device is left to handle this if it is capable; otherwise, the operating system will automatically attempt to reestablish communication. Manual mode is used by applications such as .Xr wpa_supplicant 8 that want to control the selection of an access point. .It Cm rtsthreshold Ar length Set the threshold for which transmitted frames are preceded by transmission of an RTS control frame. The .Ar length argument is the frame size in bytes and must be in the range 1 to 2346. Setting .Ar length to .Li 2346 , .Cm any , or .Cm - disables transmission of RTS frames. Not all adapters support setting the RTS threshold. .It Cm scan Initiate a scan of neighboring stations, wait for it to complete, and display all stations found. Only the super-user can initiate a scan. See .Cm list scan for information on the display. By default a background scan is done; otherwise a foreground scan is done and the station may roam to a different access point. The .Cm list scan request can be used to show recent scan results without initiating a new scan. .It Cm scanvalid Ar threshold Set the maximum time the scan cache contents are considered valid; i.e., will be used without first triggering a scan operation to refresh the data. The .Ar threshold parameter is specified in seconds and defaults to 60 seconds. The minimum setting for .Ar threshold is 10 seconds. One should take care setting this threshold; if it is set too low then attempts to roam to another access point may trigger unnecessary background scan operations. .It Cm shortgi Enable use of Short Guard Interval when operating in 802.11n on an HT channel. NB: this currently enables Short GI on both HT40 and HT20 channels. To disable Short GI use .Fl shortgi . .It Cm smps Enable use of Static Spatial Multiplexing Power Save (SMPS) when operating in 802.11n. A station operating with Static SMPS maintains only a single receive chain active (this can significantly reduce power consumption). To disable SMPS use .Fl smps . .It Cm smpsdyn Enable use of Dynamic Spatial Multiplexing Power Save (SMPS) when operating in 802.11n. A station operating with Dynamic SMPS maintains only a single receive chain active but switches to multiple receive chains when it receives an RTS frame (this can significantly reduce power consumption). Note that stations cannot distinguish between RTS/CTS intended to enable multiple receive chains and those used for other purposes. To disable SMPS use .Fl smps . .It Cm ssid Ar ssid Set the desired Service Set Identifier (aka network name). The SSID is a string up to 32 characters in length and may be specified as either a normal string or in hexadecimal when preceded by .Ql 0x . Additionally, the SSID may be cleared by setting it to .Ql - . .It Cm tdmaslot Ar slot When operating with TDMA, use the specified .Ar slot configuration. The .Ar slot is a number between 0 and the maximum number of slots in the BSS. Note that a station configured as slot 0 is a master and will broadcast beacon frames advertising the BSS; stations configured to use other slots will always scan to locate a master before they ever transmit. By default .Cm tdmaslot is set to 1. .It Cm tdmaslotcnt Ar cnt When operating with TDMA, setup a BSS with .Ar cnt slots. The slot count may be at most 8. The current implementation is only tested with two stations (i.e., point to point applications). This setting is only meaningful when a station is configured as slot 0; other stations adopt this setting from the BSS they join. By default .Cm tdmaslotcnt is set to 2. .It Cm tdmaslotlen Ar len When operating with TDMA, setup a BSS such that each station has a slot .Ar len microseconds long. The slot length must be at least 150 microseconds (1/8 TU) and no more than 65 milliseconds. Note that setting too small a slot length may result in poor channel bandwidth utilization due to factors such as timer granularity and guard time. This setting is only meaningful when a station is configured as slot 0; other stations adopt this setting from the BSS they join. By default .Cm tdmaslotlen is set to 10 milliseconds. .It Cm tdmabintval Ar intval When operating with TDMA, setup a BSS such that beacons are transmitted every .Ar intval superframes to synchronize the TDMA slot timing. A superframe is defined as the number of slots times the slot length; e.g., a BSS with two slots of 10 milliseconds has a 20 millisecond superframe. The beacon interval may not be zero. A lower setting of .Cm tdmabintval causes the timers to be resynchronized more often; this can be help if significant timer drift is observed. By default .Cm tdmabintval is set to 5. .It Cm tsn When operating as an access point with WPA/802.11i allow legacy stations to associate using static key WEP and open authentication. To disallow legacy station use of WEP, use .Fl tsn . .It Cm txpower Ar power Set the power used to transmit frames. The .Ar power argument is specified in .5 dBm units. Out of range values are truncated. Typically only a few discrete power settings are available and the driver will use the setting closest to the specified value. Not all adapters support changing the transmit power. .It Cm ucastrate Ar rate Set a fixed rate for transmitting unicast frames. Rates are specified as megabits/second in decimal; e.g.,\& 5.5 for 5.5 Mb/s. This rate should be valid for the current operating conditions; if an invalid rate is specified drivers are free to chose an appropriate rate. .It Cm wepmode Ar mode Set the desired WEP mode. Not all adapters support all modes. The set of valid modes is .Cm off , on , and .Cm mixed . The .Cm mixed mode explicitly tells the adaptor to allow association with access points which allow both encrypted and unencrypted traffic. On these adapters, .Cm on means that the access point must only allow encrypted connections. On other adapters, .Cm on is generally another name for .Cm mixed . Modes are case insensitive. .It Cm weptxkey Ar index Set the WEP key to be used for transmission. This is the same as setting the default transmission key with .Cm deftxkey . .It Cm wepkey Ar key Ns | Ns Ar index : Ns Ar key Set the selected WEP key. If an .Ar index is not given, key 1 is set. A WEP key will be either 5 or 13 characters (40 or 104 bits) depending on the local network and the capabilities of the adaptor. It may be specified either as a plain string or as a string of hexadecimal digits preceded by .Ql 0x . For maximum portability, hex keys are recommended; the mapping of text keys to WEP encryption is usually driver-specific. In particular, the Windows drivers do this mapping differently to .Fx . A key may be cleared by setting it to .Ql - . If WEP is supported then there are at least four keys. Some adapters support more than four keys. If that is the case, then the first four keys (1-4) will be the standard temporary keys and any others will be adaptor specific keys such as permanent keys stored in NVRAM. .Pp Note that you must set a default transmit key with .Cm deftxkey for the system to know which key to use in encrypting outbound traffic. .It Cm wme Enable Wireless Multimedia Extensions (WME) support, if available, for the specified interface. WME is a subset of the IEEE 802.11e standard to support the efficient communication of realtime and multimedia data. To disable WME support, use .Fl wme . Another name for this parameter is .Cm wmm . .Pp The following parameters are meaningful only when WME support is in use. Parameters are specified per-AC (Access Category) and split into those that are used by a station when acting as an access point and those for client stations in the BSS. The latter are received from the access point and may not be changed (at the station). The following Access Categories are recognized: .Pp .Bl -tag -width ".Cm AC_BK" -compact .It Cm AC_BE (or .Cm BE ) best effort delivery, .It Cm AC_BK (or .Cm BK ) background traffic, .It Cm AC_VI (or .Cm VI ) video traffic, .It Cm AC_VO (or .Cm VO ) voice traffic. .El .Pp AC parameters are case-insensitive. Traffic classification is done in the operating system using the vlan priority associated with data frames or the ToS (Type of Service) indication in IP-encapsulated frames. If neither information is present, traffic is assigned to the Best Effort (BE) category. .Bl -tag -width indent .It Cm ack Ar ac Set the ACK policy for QoS transmissions by the local station; this controls whether or not data frames transmitted by a station require an ACK response from the receiving station. To disable waiting for an ACK use .Fl ack . This parameter is applied only to the local station. .It Cm acm Ar ac Enable the Admission Control Mandatory (ACM) mechanism for transmissions by the local station. To disable the ACM use .Fl acm . On stations in a BSS this parameter is read-only and indicates the setting received from the access point. NB: ACM is not supported right now. .It Cm aifs Ar ac Ar count Set the Arbitration Inter Frame Spacing (AIFS) channel access parameter to use for transmissions by the local station. On stations in a BSS this parameter is read-only and indicates the setting received from the access point. .It Cm cwmin Ar ac Ar count Set the CWmin channel access parameter to use for transmissions by the local station. On stations in a BSS this parameter is read-only and indicates the setting received from the access point. .It Cm cwmax Ar ac Ar count Set the CWmax channel access parameter to use for transmissions by the local station. On stations in a BSS this parameter is read-only and indicates the setting received from the access point. .It Cm txoplimit Ar ac Ar limit Set the Transmission Opportunity Limit channel access parameter to use for transmissions by the local station. This parameter defines an interval of time when a WME station has the right to initiate transmissions onto the wireless medium. On stations in a BSS this parameter is read-only and indicates the setting received from the access point. .It Cm bss:aifs Ar ac Ar count Set the AIFS channel access parameter to send to stations in a BSS. This parameter is meaningful only when operating in ap mode. .It Cm bss:cwmin Ar ac Ar count Set the CWmin channel access parameter to send to stations in a BSS. This parameter is meaningful only when operating in ap mode. .It Cm bss:cwmax Ar ac Ar count Set the CWmax channel access parameter to send to stations in a BSS. This parameter is meaningful only when operating in ap mode. .It Cm bss:txoplimit Ar ac Ar limit Set the TxOpLimit channel access parameter to send to stations in a BSS. This parameter is meaningful only when operating in ap mode. .El .It Cm wps Enable Wireless Privacy Subscriber support. Note that WPS support requires a WPS-capable supplicant. To disable this function use .Fl wps . .El .Ss MAC-Based Access Control List Parameters The following parameters support an optional access control list feature available with some adapters when operating in ap mode; see .Xr wlan_acl 4 . This facility allows an access point to accept/deny association requests based on the MAC address of the station. Note that this feature does not significantly enhance security as MAC address spoofing is easy to do. .Bl -tag -width indent .It Cm mac:add Ar address Add the specified MAC address to the database. Depending on the policy setting association requests from the specified station will be allowed or denied. .It Cm mac:allow Set the ACL policy to permit association only by stations registered in the database. .It Cm mac:del Ar address Delete the specified MAC address from the database. .It Cm mac:deny Set the ACL policy to deny association only by stations registered in the database. .It Cm mac:kick Ar address Force the specified station to be deauthenticated. This typically is done to block a station after updating the address database. .It Cm mac:open Set the ACL policy to allow all stations to associate. .It Cm mac:flush Delete all entries in the database. .It Cm mac:radius Set the ACL policy to permit association only by stations approved by a RADIUS server. Note that this feature requires the .Xr hostapd 8 program be configured to do the right thing as it handles the RADIUS processing (and marks stations as authorized). .El .Ss Mesh Mode Wireless Interface Parameters The following parameters are related to a wireless interface operating in mesh mode: .Bl -tag -width indent .It Cm meshid Ar meshid Set the desired Mesh Identifier. The Mesh ID is a string up to 32 characters in length. A mesh interface must have a Mesh Identifier specified to reach an operational state. .It Cm meshttl Ar ttl Set the desired .Dq time to live for mesh forwarded packets; this is the number of hops a packet may be forwarded before it is discarded. The default setting for .Cm meshttl is 31. .It Cm meshpeering Enable or disable peering with neighbor mesh stations. Stations must peer before any data packets can be exchanged. By default .Cm meshpeering is enabled. .It Cm meshforward Enable or disable forwarding packets by a mesh interface. By default .Cm meshforward is enabled. .It Cm meshgate This attribute specifies whether or not the mesh STA activates mesh gate announcements. By default .Cm meshgate is disabled. .It Cm meshmetric Ar protocol Set the specified .Ar protocol as the link metric protocol used on a mesh network. The default protocol is called .Ar AIRTIME . The mesh interface will restart after changing this setting. .It Cm meshpath Ar protocol Set the specified .Ar protocol as the path selection protocol used on a mesh network. The only available protocol at the moment is called .Ar HWMP (Hybrid Wireless Mesh Protocol). The mesh interface will restart after changing this setting. .It Cm hwmprootmode Ar mode Stations on a mesh network can operate as .Dq root nodes . Root nodes try to find paths to all mesh nodes and advertise themselves regularly. When there is a root mesh node on a network, other mesh nodes can setup paths between themselves faster because they can use the root node to find the destination. This path may not be the best, but on-demand routing will eventually find the best path. The following modes are recognized: .Pp .Bl -tag -width ".Cm PROACTIVE" -compact .It Cm DISABLED Disable root mode. .It Cm NORMAL Send broadcast path requests every two seconds. Nodes on the mesh without a path to this root mesh station with try to discover a path to us. .It Cm PROACTIVE Send broadcast path requests every two seconds and every node must reply with a path reply even if it already has a path to this root mesh station. .It Cm RANN Send broadcast root announcement (RANN) frames. Nodes on the mesh without a path to this root mesh station with try to discover a path to us. .El By default .Cm hwmprootmode is set to .Ar DISABLED . .It Cm hwmpmaxhops Ar cnt Set the maximum number of hops allowed in an HMWP path to .Ar cnt . The default setting for .Cm hwmpmaxhops is 31. .El .Ss Compatibility Parameters The following parameters are for compatibility with other systems: .Bl -tag -width indent .It Cm nwid Ar ssid Another name for the .Cm ssid parameter. Included for .Nx compatibility. .It Cm stationname Ar name Set the name of this station. The station name is not part of the IEEE 802.11 protocol though some interfaces support it. As such it only seems to be meaningful to identical or virtually identical equipment. Setting the station name is identical in syntax to setting the SSID. One can also use .Cm station for .Bsx compatibility. .It Cm wep Another way of saying .Cm wepmode on . Included for .Bsx compatibility. .It Fl wep Another way of saying .Cm wepmode off . Included for .Bsx compatibility. .It Cm nwkey key Another way of saying: .Dq Li "wepmode on weptxkey 1 wepkey 1:key wepkey 2:- wepkey 3:- wepkey 4:-" . Included for .Nx compatibility. .It Cm nwkey Xo .Sm off .Ar n : k1 , k2 , k3 , k4 .Sm on .Xc Another way of saying .Dq Li "wepmode on weptxkey n wepkey 1:k1 wepkey 2:k2 wepkey 3:k3 wepkey 4:k4" . Included for .Nx compatibility. .It Fl nwkey Another way of saying .Cm wepmode off . Included for .Nx compatibility. .El .Ss Bridge Interface Parameters The following parameters are specific to bridge interfaces: .Bl -tag -width indent .It Cm addm Ar interface Add the interface named by .Ar interface as a member of the bridge. The interface is put into promiscuous mode so that it can receive every packet sent on the network. .It Cm deletem Ar interface Remove the interface named by .Ar interface from the bridge. Promiscuous mode is disabled on the interface when it is removed from the bridge. .It Cm maxaddr Ar size Set the size of the bridge address cache to .Ar size . The default is 2000 entries. .It Cm timeout Ar seconds Set the timeout of address cache entries to .Ar seconds seconds. If .Ar seconds is zero, then address cache entries will not be expired. The default is 1200 seconds. .It Cm addr Display the addresses that have been learned by the bridge. .It Cm static Ar interface-name Ar address Add a static entry into the address cache pointing to .Ar interface-name . Static entries are never aged out of the cache or re-placed, even if the address is seen on a different interface. .It Cm deladdr Ar address Delete .Ar address from the address cache. .It Cm flush Delete all dynamically-learned addresses from the address cache. .It Cm flushall Delete all addresses, including static addresses, from the address cache. .It Cm discover Ar interface Mark an interface as a .Dq discovering interface. When the bridge has no address cache entry (either dynamic or static) for the destination address of a packet, the bridge will forward the packet to all member interfaces marked as .Dq discovering . This is the default for all interfaces added to a bridge. .It Cm -discover Ar interface Clear the .Dq discovering attribute on a member interface. For packets without the .Dq discovering attribute, the only packets forwarded on the interface are broadcast or multicast packets and packets for which the destination address is known to be on the interface's segment. .It Cm learn Ar interface Mark an interface as a .Dq learning interface. When a packet arrives on such an interface, the source address of the packet is entered into the address cache as being a destination address on the interface's segment. This is the default for all interfaces added to a bridge. .It Cm -learn Ar interface Clear the .Dq learning attribute on a member interface. .It Cm sticky Ar interface Mark an interface as a .Dq sticky interface. Dynamically learned address entries are treated at static once entered into the cache. Sticky entries are never aged out of the cache or replaced, even if the address is seen on a different interface. .It Cm -sticky Ar interface Clear the .Dq sticky attribute on a member interface. .It Cm private Ar interface Mark an interface as a .Dq private interface. A private interface does not forward any traffic to any other port that is also a private interface. .It Cm -private Ar interface Clear the .Dq private attribute on a member interface. .It Cm span Ar interface Add the interface named by .Ar interface as a span port on the bridge. Span ports transmit a copy of every frame received by the bridge. This is most useful for snooping a bridged network passively on another host connected to one of the span ports of the bridge. .It Cm -span Ar interface Delete the interface named by .Ar interface from the list of span ports of the bridge. .It Cm stp Ar interface Enable Spanning Tree protocol on .Ar interface . The .Xr if_bridge 4 driver has support for the IEEE 802.1D Spanning Tree protocol (STP). Spanning Tree is used to detect and remove loops in a network topology. .It Cm -stp Ar interface Disable Spanning Tree protocol on .Ar interface . This is the default for all interfaces added to a bridge. .It Cm edge Ar interface Set .Ar interface as an edge port. An edge port connects directly to end stations cannot create bridging loops in the network, this allows it to transition straight to forwarding. .It Cm -edge Ar interface Disable edge status on .Ar interface . .It Cm autoedge Ar interface Allow .Ar interface to automatically detect edge status. This is the default for all interfaces added to a bridge. .It Cm -autoedge Ar interface Disable automatic edge status on .Ar interface . .It Cm ptp Ar interface Set the .Ar interface as a point to point link. This is required for straight transitions to forwarding and should be enabled on a direct link to another RSTP capable switch. .It Cm -ptp Ar interface Disable point to point link status on .Ar interface . This should be disabled for a half duplex link and for an interface connected to a shared network segment, like a hub or a wireless network. .It Cm autoptp Ar interface Automatically detect the point to point status on .Ar interface by checking the full duplex link status. This is the default for interfaces added to the bridge. .It Cm -autoptp Ar interface Disable automatic point to point link detection on .Ar interface . .It Cm maxage Ar seconds Set the time that a Spanning Tree protocol configuration is valid. The default is 20 seconds. The minimum is 6 seconds and the maximum is 40 seconds. .It Cm fwddelay Ar seconds Set the time that must pass before an interface begins forwarding packets when Spanning Tree is enabled. The default is 15 seconds. The minimum is 4 seconds and the maximum is 30 seconds. .It Cm hellotime Ar seconds Set the time between broadcasting of Spanning Tree protocol configuration messages. The hello time may only be changed when operating in legacy stp mode. The default is 2 seconds. The minimum is 1 second and the maximum is 2 seconds. .It Cm priority Ar value Set the bridge priority for Spanning Tree. The default is 32768. The minimum is 0 and the maximum is 61440. .It Cm proto Ar value Set the Spanning Tree protocol. The default is rstp. The available options are stp and rstp. .It Cm holdcnt Ar value Set the transmit hold count for Spanning Tree. This is the number of packets transmitted before being rate limited. The default is 6. The minimum is 1 and the maximum is 10. .It Cm ifpriority Ar interface Ar value Set the Spanning Tree priority of .Ar interface to .Ar value . The default is 128. The minimum is 0 and the maximum is 240. .It Cm ifpathcost Ar interface Ar value Set the Spanning Tree path cost of .Ar interface to .Ar value . The default is calculated from the link speed. To change a previously selected path cost back to automatic, set the cost to 0. The minimum is 1 and the maximum is 200000000. .It Cm ifmaxaddr Ar interface Ar size Set the maximum number of hosts allowed from an interface, packets with unknown source addresses are dropped until an existing host cache entry expires or is removed. Set to 0 to disable. .El .Ss Link Aggregation and Link Failover Parameters The following parameters are specific to lagg interfaces: .Bl -tag -width indent .It Cm laggtype Ar type When creating a lagg interface the type can be specified as either .Cm ethernet or .Cm infiniband . If not specified ethernet is the default lagg type. .It Cm laggport Ar interface Add the interface named by .Ar interface as a port of the aggregation interface. .It Cm -laggport Ar interface Remove the interface named by .Ar interface from the aggregation interface. .It Cm laggproto Ar proto Set the aggregation protocol. The default is .Li failover . The available options are .Li failover , .Li lacp , .Li loadbalance , .Li roundrobin , .Li broadcast and .Li none . .It Cm lagghash Ar option Ns Oo , Ns Ar option Oc Set the packet layers to hash for aggregation protocols which load balance. The default is .Dq l2,l3,l4 . The options can be combined using commas. .Pp .Bl -tag -width ".Cm l2" -compact .It Cm l2 src/dst mac address and optional vlan number. .It Cm l3 src/dst address for IPv4 or IPv6. .It Cm l4 src/dst port for TCP/UDP/SCTP. .El .It Cm -use_flowid Enable local hash computation for RSS hash on the interface. The .Li loadbalance and .Li lacp modes will use the RSS hash from the network card if available to avoid computing one, this may give poor traffic distribution if the hash is invalid or uses less of the protocol header information. .Cm -use_flowid disables use of RSS hash from the network card. The default value can be set via the .Va net.link.lagg.default_use_flowid .Xr sysctl 8 variable. .Li 0 means .Dq disabled and .Li 1 means .Dq enabled . .It Cm use_flowid Use the RSS hash from the network card if available. .It Cm flowid_shift Ar number Set a shift parameter for RSS local hash computation. Hash is calculated by using flowid bits in a packet header mbuf which are shifted by the number of this parameter. .It Cm use_numa Enable selection of egress ports based on the native .Xr numa 4 domain for the packets being transmitted. This is currently only implemented for lacp mode. This works only on .Xr numa 4 hardware, running a kernel compiled with the .Xr numa 4 option, and when interfaces from multiple .Xr numa 4 domains are ports of the aggregation interface. .It Cm -use_numa Disable selection of egress ports based on the native .Xr numa 4 domain for the packets being transmitted. .It Cm lacp_fast_timeout Enable lacp fast-timeout on the interface. .It Cm -lacp_fast_timeout Disable lacp fast-timeout on the interface. .It Cm lacp_strict Enable lacp strict compliance on the interface. The default value can be set via the .Va net.link.lagg.lacp.default_strict_mode .Xr sysctl 8 variable. .Li 0 means .Dq disabled and .Li 1 means .Dq enabled . .It Cm -lacp_strict Disable lacp strict compliance on the interface. .It Cm rr_limit Ar number Configure a stride for an interface in round-robin mode. The default stride is 1. .El .Ss Generic IP Tunnel Parameters The following parameters apply to IP tunnel interfaces, .Xr gif 4 : .Bl -tag -width indent .It Cm tunnel Ar src_addr dest_addr Configure the physical source and destination address for IP tunnel interfaces. The arguments .Ar src_addr and .Ar dest_addr are interpreted as the outer source/destination for the encapsulating IPv4/IPv6 header. .It Fl tunnel Unconfigure the physical source and destination address for IP tunnel interfaces previously configured with .Cm tunnel . .It Cm deletetunnel Another name for the .Fl tunnel parameter. .It Cm accept_rev_ethip_ver Set a flag to accept both correct EtherIP packets and ones with reversed version field. Enabled by default. This is for backward compatibility with .Fx 6.1 , 6.2, 6.3, 7.0, and 7.1. .It Cm -accept_rev_ethip_ver Clear a flag .Cm accept_rev_ethip_ver . .It Cm ignore_source Set a flag to accept encapsulated packets destined to this host independently from source address. This may be useful for hosts, that receive encapsulated packets from the load balancers. .It Cm -ignore_source Clear a flag .Cm ignore_source . .It Cm send_rev_ethip_ver Set a flag to send EtherIP packets with reversed version field intentionally. Disabled by default. This is for backward compatibility with .Fx 6.1 , 6.2, 6.3, 7.0, and 7.1. .It Cm -send_rev_ethip_ver Clear a flag .Cm send_rev_ethip_ver . .El .Ss GRE Tunnel Parameters The following parameters apply to GRE tunnel interfaces, .Xr gre 4 : .Bl -tag -width indent .It Cm tunnel Ar src_addr dest_addr Configure the physical source and destination address for GRE tunnel interfaces. The arguments .Ar src_addr and .Ar dest_addr are interpreted as the outer source/destination for the encapsulating IPv4/IPv6 header. .It Fl tunnel Unconfigure the physical source and destination address for GRE tunnel interfaces previously configured with .Cm tunnel . .It Cm deletetunnel Another name for the .Fl tunnel parameter. .It Cm grekey Ar key Configure the GRE key to be used for outgoing packets. Note that .Xr gre 4 will always accept GRE packets with invalid or absent keys. This command will result in a four byte MTU reduction on the interface. .El .Ss Packet Filter State Table Sychronisation Parameters The following parameters are specific to .Xr pfsync 4 interfaces: .Bl -tag -width indent .It Cm syncdev Ar iface Use the specified interface to send and receive pfsync state synchronisation messages. .It Fl syncdev Stop sending pfsync state synchronisation messages over the network. .It Cm syncpeer Ar peer_address Set the destination address for the state synchronization messages sent. The .Ar peer_address is normally the IPv4 or IPv6 address of the other host taking part in the pfsync cluster. .Pp When the .Ar peer_address is set to a unicast IP address, the pfsync link will behave as point-to-point rather than using multicast to broadcast the messages. .Pp When the .Ar peer_address is set to ff12::f0, the state synchronization messages will be broadcast using multicast over IPv6. .It Fl syncpeer Unset the syncpeer. Packets will then be broadcast using multicast over IPv4. .It Cm maxupd Ar n Set the maximum number of updates for a single state which can be collapsed into one. This is an 8-bit number; the default value is 128. .It Cm defer Defer transmission of the first packet in a state until a peer has acknowledged that the associated state has been inserted. .It Fl defer Do not defer the first packet in a state. This is the default. .It Fl version Ar n Configure message format for compatibility with older versions of FreeBSD. Refer to .Xr pfsync 4 for details. .El .Ss VLAN Parameters The following parameters are specific to .Xr vlan 4 interfaces: .Bl -tag -width indent .It Cm vlan Ar vlan_tag Set the VLAN tag value to .Ar vlan_tag . This value is a 12-bit VLAN Identifier (VID) which is used to create an 802.1Q or 802.1ad VLAN header for packets sent from the .Xr vlan 4 interface. Note that .Cm vlan and .Cm vlandev must both be set at the same time. .It Cm vlanproto Ar vlan_proto Set the VLAN encapsulation protocol to .Ar vlan_proto . Supported encapsulation protocols are currently: .Bl -tag .It Cm 802.1Q Default. .It Cm 802.1ad .It Cm QinQ Same as .Cm 802.1ad . .El .It Cm vlanpcp Ar priority_code_point Priority code point .Pq Dv PCP is an 3-bit field which refers to the IEEE 802.1p class of service and maps to the frame priority level. .Pp Values in order of priority are: .Cm 1 .Pq Dv Background (lowest) , .Cm 0 .Pq Dv Best effort (default) , .Cm 2 .Pq Dv Excellent effort , .Cm 3 .Pq Dv Critical applications , .Cm 4 .Pq Dv Video, < 100ms latency and jitter , .Cm 5 .Pq Dv Voice, < 10ms latency and jitter , .Cm 6 .Pq Dv Internetwork control , .Cm 7 .Pq Dv Network control (highest) . .It Cm vlandev Ar iface Associate the physical interface .Ar iface with a .Xr vlan 4 interface. Packets transmitted through the .Xr vlan 4 interface will be diverted to the specified physical interface .Ar iface with 802.1Q VLAN encapsulation. Packets with 802.1Q encapsulation received by the parent interface with the correct VLAN Identifier will be diverted to the associated .Xr vlan 4 pseudo-interface. The .Xr vlan 4 interface is assigned a copy of the parent interface's flags and the parent's Ethernet address. The .Cm vlandev and .Cm vlan must both be set at the same time. If the .Xr vlan 4 interface already has a physical interface associated with it, this command will fail. To change the association to another physical interface, the existing association must be cleared first. .Pp Note: if the hardware tagging capability is set on the parent interface, the .Xr vlan 4 pseudo interface's behavior changes: the .Xr vlan 4 interface recognizes that the parent interface supports insertion and extraction of VLAN tags on its own (usually in firmware) and that it should pass packets to and from the parent unaltered. .It Fl vlandev Op Ar iface If the driver is a .Xr vlan 4 pseudo device, disassociate the parent interface from it. This breaks the link between the .Xr vlan 4 interface and its parent, clears its VLAN Identifier, flags and its link address and shuts the interface down. The .Ar iface argument is useless and hence deprecated. .El .Ss Virtual eXtensible LAN Parameters The following parameters are used to configure .Xr vxlan 4 interfaces. .Bl -tag -width indent .It Cm vxlanid Ar identifier This value is a 24-bit VXLAN Network Identifier (VNI) that identifies the virtual network segment membership of the interface. .It Cm vxlanlocal Ar address The source address used in the encapsulating IPv4/IPv6 header. The address should already be assigned to an existing interface. When the interface is configured in unicast mode, the listening socket is bound to this address. .It Cm vxlanremote Ar address The interface can be configured in a unicast, or point-to-point, mode to create a tunnel between two hosts. This is the IP address of the remote end of the tunnel. .It Cm vxlangroup Ar address The interface can be configured in a multicast mode to create a virtual network of hosts. This is the IP multicast group address the interface will join. .It Cm vxlanlocalport Ar port The port number the interface will listen on. The default port number is 4789. .It Cm vxlanremoteport Ar port The destination port number used in the encapsulating IPv4/IPv6 header. The remote host should be listening on this port. The default port number is 4789. Note some other implementations, such as Linux, do not default to the IANA assigned port, but instead listen on port 8472. .It Cm vxlanportrange Ar low high The range of source ports used in the encapsulating IPv4/IPv6 header. The port selected within the range is based on a hash of the inner frame. A range is useful to provide entropy within the outer IP header for more effective load balancing. The default range is between the .Xr sysctl 8 variables .Va net.inet.ip.portrange.first and .Va net.inet.ip.portrange.last .It Cm vxlantimeout Ar timeout The maximum time, in seconds, before an entry in the forwarding table is pruned. The default is 1200 seconds (20 minutes). .It Cm vxlanmaxaddr Ar max The maximum number of entries in the forwarding table. The default is 2000. .It Cm vxlandev Ar dev When the interface is configured in multicast mode, the .Cm dev interface is used to transmit IP multicast packets. .It Cm vxlanttl Ar ttl The TTL used in the encapsulating IPv4/IPv6 header. The default is 64. .It Cm vxlanlearn The source IP address and inner source Ethernet MAC address of received packets are used to dynamically populate the forwarding table. When in multicast mode, an entry in the forwarding table allows the interface to send the frame directly to the remote host instead of broadcasting the frame to the multicast group. This is the default. .It Fl vxlanlearn The forwarding table is not populated by received packets. .It Cm vxlanflush Delete all dynamically-learned addresses from the forwarding table. .It Cm vxlanflushall Delete all addresses, including static addresses, from the forwarding table. .El .Ss CARP Parameters The following parameters are used to configure .Xr carp 4 protocol on an interface: .Bl -tag -width indent .It Cm vhid Ar n Set the virtual host ID. This is a required setting to initiate .Xr carp 4 . If the virtual host ID does not exist yet, it is created and attached to the interface, otherwise configuration of an existing vhid is adjusted. If the .Cm vhid keyword is supplied along with an .Dq inet6 or .Dq inet address, then this address is configured to be run under control of the specified vhid. Whenever a last address that refers to a particular vhid is removed from an interface, the vhid is automatically removed from interface and destroyed. Any other configuration parameters for the .Xr carp 4 protocol should be supplied along with the .Cm vhid keyword. Acceptable values for vhid are 1 to 255. .It Cm advbase Ar seconds Specifies the base of the advertisement interval in seconds. The acceptable values are 1 to 255. The default value is 1. .It Cm advskew Ar interval Specifies the skew to add to the base advertisement interval to make one host advertise slower than another host. It is specified in 1/256 of seconds. The acceptable values are 1 to 254. The default value is 0. .It Cm pass Ar phrase Set the authentication key to .Ar phrase . .It Cm state Ar state Forcibly change state of a given vhid. The following states are recognized: .Cm MASTER and .Cm BACKUP . .It Cm peer Ar address Set the address to send (IPv4) .Xr carp 4 announcements to. .It Cm mcast Restore the default destination address for (IPv4) .Xr carp 4 announcements, which is 224.0.0.18. .It Cm peer6 Ar address Set the address to send (IPv6) .Xr carp 4 announcements to. .It Cm mcast6 Restore the default destination address for (IPv4) .Xr carp 4 announcements, which is ff02::12. .El .Sh ENVIRONMENT The following environment variables affect the execution of .Nm : .Bl -tag -width IFCONFIG_FORMAT .It Ev IFCONFIG_FORMAT This variable can contain a specification of the output format. See the description of the .Fl f flag for more details. .El .Sh EXAMPLES Assign the IPv4 address .Li 192.0.2.10 , with a network mask of .Li 255.255.255.0 , to the interface .Li em0 : .Dl # ifconfig em0 inet 192.0.2.10 netmask 255.255.255.0 .Pp Add the IPv4 address .Li 192.0.2.45 , with the CIDR network prefix .Li /28 , to the interface .Li em0 : .Dl # ifconfig em0 inet 192.0.2.45/28 alias .Pp Remove the IPv4 address .Li 192.0.2.45 from the interface .Li em0 : .Dl # ifconfig em0 inet 192.0.2.45 -alias .Pp Enable IPv6 functionality of the interface: .Dl # ifconfig em0 inet6 -ifdisabled .Pp Add the IPv6 address .Li 2001:DB8:DBDB::123/48 to the interface .Li em0 : .Dl # ifconfig em0 inet6 2001:db8:bdbd::123 prefixlen 48 alias Note that lower case hexadecimal IPv6 addresses are acceptable. .Pp Remove the IPv6 address added in the above example, using the .Li / character as shorthand for the network prefix: .Dl # ifconfig em0 inet6 2001:db8:bdbd::123/48 -alias .Pp Configure a single CARP redundant address on igb0, and then switch it to be master: .Bd -literal -offset indent -compact # ifconfig igb0 vhid 1 10.0.0.1/24 pass foobar up # ifconfig igb0 vhid 1 state master .Ed .Pp Configure the interface .Li xl0 , to use 100baseTX, full duplex Ethernet media options: .Dl # ifconfig xl0 media 100baseTX mediaopt full-duplex .Pp Label the em0 interface as an uplink: .Dl # ifconfig em0 description \&"Uplink to Gigabit Switch 2\&" .Pp Create the software network interface .Li gif1 : .Dl # ifconfig gif1 create .Pp Destroy the software network interface .Li gif1 : .Dl # ifconfig gif1 destroy .Pp Display available wireless networks using .Li wlan0 : .Dl # ifconfig wlan0 list scan .Pp Display inet and inet6 address subnet masks in CIDR notation .Dl # ifconfig -f inet:cidr,inet6:cidr .Pp Display interfaces that are up with the exception of loopback .Dl # ifconfig -a -u -G lo .Pp Display a list of interface names beloning to the wlan group: .Bd -literal -offset indent -compact # ifconfig -g wlan wlan0 wlan1 .Ed .Pp Display details about the interfaces belonging to the wlan group: .Bd -literal -offset indent -compact # ifconfig -a -g wlan wlan0: flags=8843 metric 0 mtu 1500 ether 75:4c:61:6b:7a:73 inet6 fe80::4c75:636a:616e:ffd8%wlan0 prefixlen 64 scopeid 0x3 inet6 2001:5761:6e64:6152:6f6d:616e:fea4:ffe2 prefixlen 64 autoconf inet 192.168.10.5 netmask 0xffffff00 broadcast 192.168.10.255 groups: wlan ssid "Hotspot" channel 11 (2462 MHz 11g) bssid 12:34:ff:ff:43:21 regdomain ETSI country DE authmode WPA2/802.11i privacy ON deftxkey UNDEF AES-CCM 2:128-bit AES-CCM 3:128-bit txpower 30 bmiss 10 scanvalid 60 protmode CTS wme roaming MANUAL parent interface: iwm0 media: IEEE 802.11 Wireless Ethernet DS/2Mbps mode 11g status: associated nd6 options=23 wlan1: flags=8843 metric 0 mtu 1500 ether 00:50:69:6f:74:72 groups: wlan ssid "" channel 2 (2417 MHz 11g) regdomain FCC country US authmode OPEN privacy OFF txpower 30 bmiss 7 scanvalid 60 bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS wme bintval 0 parent interface: rum0 media: IEEE 802.11 Wireless Ethernet autoselect (autoselect) status: no carrier nd6 options=29 .Ed .Pp Set a randomly-generated MAC address on tap0: .Dl # ifconfig tap0 ether random .Sh DIAGNOSTICS Messages indicating the specified interface does not exist, the requested address is unknown, or the user is not privileged and tried to alter an interface's configuration. .Sh SEE ALSO .Xr netstat 1 , .Xr carp 4 , .Xr gif 4 , .Xr netintro 4 , .Xr pfsync 4 , .Xr polling 4 , .Xr vlan 4 , .Xr vxlan 4 , .Xr devd.conf 5 , .Xr devd 8 , .Xr jail 8 , .Xr rc 8 , .Xr routed 8 , .Xr sysctl 8 .Sh HISTORY The .Nm utility appeared in .Bx 4.2 . .Sh BUGS Basic IPv6 node operation requires a link-local address on each interface configured for IPv6. Normally, such an address is automatically configured by the kernel on each interface added to the system or enabled; this behavior may be disabled by setting per-interface flag .Cm -auto_linklocal . The default value of this flag is 1 and can be disabled by using the sysctl MIB variable .Va net.inet6.ip6.auto_linklocal . .Pp Do not configure IPv6 addresses with no link-local address by using .Nm . It can result in unexpected behaviors of the kernel. diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 5ee41bb24b71..2cbe7a881bd0 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,2096 +1,2099 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #ifdef JAIL #include #endif #include #include #include #include #include #include #include #include #include #include #include #include /* IP */ #include #include #include #include #include #include #include #include #include #include #ifdef JAIL #include #endif #include #include #include #include #include #include #include "ifconfig.h" ifconfig_handle_t *lifh; #ifdef WITHOUT_NETLINK static char *descr = NULL; static size_t descrlen = 64; #endif static int setaddr; static int setmask; static int doalias; static int clearaddr; static int newaddr = 1; int exit_code = 0; static char ifname_to_print[IFNAMSIZ]; /* Helper for printifnamemaybe() */ /* Formatter Strings */ char *f_inet, *f_inet6, *f_ether, *f_addr; #ifdef WITHOUT_NETLINK static void list_interfaces_ioctl(if_ctx *ctx); static void status(if_ctx *ctx, const struct sockaddr_dl *sdl, struct ifaddrs *ifa); #endif static _Noreturn void usage(void); static void Perrorc(const char *cmd, int error); static int getifflags(const char *ifname, int us, bool err_ok); static struct afswtch *af_getbyname(const char *name); static struct option *opts = NULL; struct ifa_order_elt { int if_order; int af_orders[255]; struct ifaddrs *ifa; TAILQ_ENTRY(ifa_order_elt) link; }; TAILQ_HEAD(ifa_queue, ifa_order_elt); static struct module_map_entry { const char *ifname; const char *kldname; } module_map[] = { { .ifname = "tun", .kldname = "if_tuntap", }, { .ifname = "tap", .kldname = "if_tuntap", }, { .ifname = "vmnet", .kldname = "if_tuntap", }, { .ifname = "ipsec", .kldname = "ipsec", }, { /* * This mapping exists because there is a conflicting enc module * in CAM. ifconfig's guessing behavior will attempt to match * the ifname to a module as well as if_${ifname} and clash with * CAM enc. This is an assertion of the correct module to load. */ .ifname = "enc", .kldname = "if_enc", }, }; void opt_register(struct option *p) { p->next = opts; opts = p; } static void usage(void) { char options[1024]; struct option *p; /* XXX not right but close enough for now */ options[0] = '\0'; for (p = opts; p != NULL; p = p->next) { strlcat(options, p->opt_usage, sizeof(options)); strlcat(options, " ", sizeof(options)); } fprintf(stderr, "usage: ifconfig [-j jail] [-f type:format] %sinterface address_family\n" " [address [dest_address]] [parameters]\n" " ifconfig [-j jail] interface create\n" " ifconfig [-j jail] -a %s[-d] [-m] [-u] [-v] [address_family]\n" " ifconfig [-j jail] -l [-d] [-u] [address_family]\n" " ifconfig [-j jail] %s[-d] [-m] [-u] [-v]\n", options, options, options); exit(1); } static void ifname_update(if_ctx *ctx, const char *name) { strlcpy(ctx->_ifname_storage_ioctl, name, sizeof(ctx->_ifname_storage_ioctl)); ctx->ifname = ctx->_ifname_storage_ioctl; strlcpy(ifname_to_print, name, sizeof(ifname_to_print)); } static void ifr_set_name(struct ifreq *ifr, const char *name) { strlcpy(ifr->ifr_name, name, sizeof(ifr->ifr_name)); } int ioctl_ctx_ifr(if_ctx *ctx, unsigned long cmd, struct ifreq *ifr) { ifr_set_name(ifr, ctx->ifname); return (ioctl_ctx(ctx, cmd, ifr)); } void ifcreate_ioctl(if_ctx *ctx, struct ifreq *ifr) { char ifname_orig[IFNAMSIZ]; strlcpy(ifname_orig, ifr->ifr_name, sizeof(ifname_orig)); if (ioctl(ctx->io_s, SIOCIFCREATE2, ifr) < 0) { switch (errno) { case EEXIST: errx(1, "interface %s already exists", ifr->ifr_name); default: err(1, "SIOCIFCREATE2 (%s)", ifr->ifr_name); } } if (strncmp(ifname_orig, ifr->ifr_name, sizeof(ifname_orig)) != 0) ifname_update(ctx, ifr->ifr_name); } #ifdef WITHOUT_NETLINK static int calcorders(struct ifaddrs *ifa, struct ifa_queue *q) { struct ifaddrs *prev; struct ifa_order_elt *cur; unsigned int ord, af, ifa_ord; prev = NULL; cur = NULL; ord = 0; ifa_ord = 0; while (ifa != NULL) { if (prev == NULL || strcmp(ifa->ifa_name, prev->ifa_name) != 0) { cur = calloc(1, sizeof(*cur)); if (cur == NULL) return (-1); TAILQ_INSERT_TAIL(q, cur, link); cur->if_order = ifa_ord ++; cur->ifa = ifa; ord = 0; } if (ifa->ifa_addr) { af = ifa->ifa_addr->sa_family; if (af < nitems(cur->af_orders) && cur->af_orders[af] == 0) cur->af_orders[af] = ++ord; } prev = ifa; ifa = ifa->ifa_next; } return (0); } static int cmpifaddrs(struct ifaddrs *a, struct ifaddrs *b, struct ifa_queue *q) { struct ifa_order_elt *cur, *e1, *e2; unsigned int af1, af2; int ret; e1 = e2 = NULL; ret = strcmp(a->ifa_name, b->ifa_name); if (ret != 0) { TAILQ_FOREACH(cur, q, link) { if (e1 && e2) break; if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) e1 = cur; else if (strcmp(cur->ifa->ifa_name, b->ifa_name) == 0) e2 = cur; } if (!e1 || !e2) return (0); else return (e1->if_order - e2->if_order); } else if (a->ifa_addr != NULL && b->ifa_addr != NULL) { TAILQ_FOREACH(cur, q, link) { if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) { e1 = cur; break; } } if (!e1) return (0); af1 = a->ifa_addr->sa_family; af2 = b->ifa_addr->sa_family; if (af1 < nitems(e1->af_orders) && af2 < nitems(e1->af_orders)) return (e1->af_orders[af1] - e1->af_orders[af2]); } return (0); } #endif static void freeformat(void) { if (f_inet != NULL) free(f_inet); if (f_inet6 != NULL) free(f_inet6); if (f_ether != NULL) free(f_ether); if (f_addr != NULL) free(f_addr); } static void setformat(char *input) { char *formatstr, *category, *modifier; formatstr = strdup(input); while ((category = strsep(&formatstr, ",")) != NULL) { modifier = strchr(category, ':'); if (modifier == NULL || modifier[1] == '\0') { warnx("Skipping invalid format specification: %s\n", category); continue; } /* Split the string on the separator, then seek past it */ modifier[0] = '\0'; modifier++; if (strcmp(category, "addr") == 0) f_addr = strdup(modifier); else if (strcmp(category, "ether") == 0) f_ether = strdup(modifier); else if (strcmp(category, "inet") == 0) f_inet = strdup(modifier); else if (strcmp(category, "inet6") == 0) f_inet6 = strdup(modifier); } free(formatstr); } #ifdef WITHOUT_NETLINK static struct ifaddrs * sortifaddrs(struct ifaddrs *list, int (*compare)(struct ifaddrs *, struct ifaddrs *, struct ifa_queue *), struct ifa_queue *q) { struct ifaddrs *right, *temp, *last, *result, *next, *tail; right = list; temp = list; last = list; result = NULL; next = NULL; tail = NULL; if (!list || !list->ifa_next) return (list); while (temp && temp->ifa_next) { last = right; right = right->ifa_next; temp = temp->ifa_next->ifa_next; } last->ifa_next = NULL; list = sortifaddrs(list, compare, q); right = sortifaddrs(right, compare, q); while (list || right) { if (!right) { next = list; list = list->ifa_next; } else if (!list) { next = right; right = right->ifa_next; } else if (compare(list, right, q) <= 0) { next = list; list = list->ifa_next; } else { next = right; right = right->ifa_next; } if (!result) result = next; else tail->ifa_next = next; tail = next; } return (result); } #endif static void printifnamemaybe(void) { if (ifname_to_print[0] != '\0') printf("%s\n", ifname_to_print); } static void list_interfaces(if_ctx *ctx) { #ifdef WITHOUT_NETLINK list_interfaces_ioctl(ctx); #else list_interfaces_nl(ctx->args); #endif } static char * args_peek(struct ifconfig_args *args) { if (args->argc > 0) return (args->argv[0]); return (NULL); } static char * args_pop(struct ifconfig_args *args) { if (args->argc == 0) return (NULL); char *arg = args->argv[0]; args->argc--; args->argv++; return (arg); } static void args_parse(struct ifconfig_args *args, int argc, char *argv[]) { char options[1024]; struct option *p; int c; /* Parse leading line options */ - strlcpy(options, "G:adf:j:klmnuv", sizeof(options)); + strlcpy(options, "G:adDf:j:klmnuv", sizeof(options)); for (p = opts; p != NULL; p = p->next) strlcat(options, p->opt, sizeof(options)); while ((c = getopt(argc, argv, options)) != -1) { switch (c) { case 'a': /* scan all interfaces */ args->all = true; break; case 'd': /* restrict scan to "down" interfaces */ args->downonly = true; break; + case 'D': /* Print driver name */ + args->drivername = true; + break; case 'f': if (optarg == NULL) usage(); setformat(optarg); break; case 'G': if (optarg == NULL || args->all == 0) usage(); args->nogroup = optarg; break; case 'j': #ifdef JAIL if (optarg == NULL) usage(); args->jail_name = optarg; #else Perror("not built with jail support"); #endif break; case 'k': args->printkeys = true; break; case 'l': /* scan interface names only */ args->namesonly = true; break; case 'm': /* show media choices in status */ args->supmedia = true; break; case 'n': /* suppress module loading */ args->noload = true; break; case 'u': /* restrict scan to "up" interfaces */ args->uponly = true; break; case 'v': args->verbose++; break; case 'g': if (args->all) { if (optarg == NULL) usage(); args->matchgroup = optarg; break; } /* FALLTHROUGH */ default: for (p = opts; p != NULL; p = p->next) if (p->opt[0] == c) { p->cb(optarg); break; } if (p == NULL) usage(); break; } } argc -= optind; argv += optind; /* -l cannot be used with -a or -m */ if (args->namesonly && (args->all || args->supmedia)) usage(); /* nonsense.. */ if (args->uponly && args->downonly) usage(); /* no arguments is equivalent to '-a' */ if (!args->namesonly && argc < 1) args->all = 1; /* -a and -l allow an address family arg to limit the output */ if (args->all || args->namesonly) { if (argc > 1) usage(); if (argc == 1) { const struct afswtch *afp = af_getbyname(*argv); if (afp == NULL) { warnx("Address family '%s' unknown.", *argv); usage(); } if (afp->af_name != NULL) argc--, argv++; /* leave with afp non-zero */ args->afp = afp; } } else { /* not listing, need an argument */ if (argc < 1) usage(); } args->argc = argc; args->argv = argv; } static int ifconfig(if_ctx *ctx, int iscreate, const struct afswtch *uafp) { #ifdef WITHOUT_NETLINK return (ifconfig_ioctl(ctx, iscreate, uafp)); #else return (ifconfig_nl(ctx, iscreate, uafp)); #endif } static bool isargcreate(const char *arg) { if (arg == NULL) return (false); if (strcmp(arg, "create") == 0 || strcmp(arg, "plumb") == 0) return (true); return (false); } static bool isnametoolong(const char *ifname) { return (strlen(ifname) >= IFNAMSIZ); } int main(int ac, char *av[]) { char *envformat; int flags; #ifdef JAIL int jid; #endif struct ifconfig_args _args = {}; struct ifconfig_args *args = &_args; struct ifconfig_context ctx = { .args = args, .io_s = -1, }; f_inet = f_inet6 = f_ether = f_addr = NULL; lifh = ifconfig_open(); if (lifh == NULL) err(EXIT_FAILURE, "ifconfig_open"); envformat = getenv("IFCONFIG_FORMAT"); if (envformat != NULL) setformat(envformat); /* * Ensure we print interface name when expected to, * even if we terminate early due to error. */ atexit(printifnamemaybe); args_parse(args, ac, av); #ifdef JAIL if (args->jail_name) { jid = jail_getid(args->jail_name); if (jid == -1) Perror("jail not found"); if (jail_attach(jid) != 0) Perror("cannot attach to jail"); } #endif if (!args->all && !args->namesonly) { /* not listing, need an argument */ args->ifname = args_pop(args); ctx.ifname = args->ifname; /* check and maybe load support for this interface */ ifmaybeload(args, args->ifname); char *arg = args_peek(args); if (if_nametoindex(args->ifname) == 0) { /* * NOTE: We must special-case the `create' command * right here as we would otherwise fail when trying * to find the interface. */ if (isargcreate(arg)) { if (isnametoolong(args->ifname)) errx(1, "%s: cloning name too long", args->ifname); ifconfig(&ctx, 1, NULL); exit(exit_code); } #ifdef JAIL /* * NOTE: We have to special-case the `-vnet' command * right here as we would otherwise fail when trying * to find the interface as it lives in another vnet. */ if (arg != NULL && (strcmp(arg, "-vnet") == 0)) { if (isnametoolong(args->ifname)) errx(1, "%s: interface name too long", args->ifname); ifconfig(&ctx, 0, NULL); exit(exit_code); } #endif errx(1, "interface %s does not exist", args->ifname); } else { /* * Do not allow use `create` command as hostname if * address family is not specified. */ if (isargcreate(arg)) { if (args->argc == 1) errx(1, "interface %s already exists", args->ifname); args_pop(args); } } } /* Check for address family */ if (args->argc > 0) { args->afp = af_getbyname(args_peek(args)); if (args->afp != NULL) args_pop(args); } /* * Check for a requested configuration action on a single interface, * which doesn't require building, sorting, and searching the entire * system address list */ if ((args->argc > 0) && (args->ifname != NULL)) { if (isnametoolong(args->ifname)) warnx("%s: interface name too long, skipping", args->ifname); else { flags = getifflags(args->ifname, -1, false); if (!(((flags & IFF_CANTCONFIG) != 0) || (args->downonly && (flags & IFF_UP) != 0) || (args->uponly && (flags & IFF_UP) == 0))) ifconfig(&ctx, 0, args->afp); } goto done; } args->allfamilies = args->afp == NULL; list_interfaces(&ctx); done: freeformat(); ifconfig_close(lifh); exit(exit_code); } bool match_ether(const struct sockaddr_dl *sdl) { switch (sdl->sdl_type) { case IFT_ETHER: case IFT_L2VLAN: case IFT_BRIDGE: if (sdl->sdl_alen == ETHER_ADDR_LEN) return (true); default: return (false); } } bool match_if_flags(struct ifconfig_args *args, int if_flags) { if ((if_flags & IFF_CANTCONFIG) != 0) return (false); if (args->downonly && (if_flags & IFF_UP) != 0) return (false); if (args->uponly && (if_flags & IFF_UP) == 0) return (false); return (true); } #ifdef WITHOUT_NETLINK static bool match_afp(const struct afswtch *afp, int sa_family, const struct sockaddr_dl *sdl) { if (afp == NULL) return (true); /* special case for "ether" address family */ if (!strcmp(afp->af_name, "ether")) { if (sdl == NULL || !match_ether(sdl)) return (false); return (true); } return (afp->af_af == sa_family); } static void list_interfaces_ioctl(if_ctx *ctx) { struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q); struct ifaddrs *ifap, *sifap, *ifa; struct ifa_order_elt *cur, *tmp; char *namecp = NULL; int ifindex; struct ifconfig_args *args = ctx->args; if (getifaddrs(&ifap) != 0) err(EXIT_FAILURE, "getifaddrs"); char *cp = NULL; if (calcorders(ifap, &q) != 0) err(EXIT_FAILURE, "calcorders"); sifap = sortifaddrs(ifap, cmpifaddrs, &q); TAILQ_FOREACH_SAFE(cur, &q, link, tmp) free(cur); ifindex = 0; for (ifa = sifap; ifa; ifa = ifa->ifa_next) { struct ifreq paifr = {}; const struct sockaddr_dl *sdl; strlcpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { memcpy(&paifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); } if (args->ifname != NULL && strcmp(args->ifname, ifa->ifa_name) != 0) continue; if (ifa->ifa_addr->sa_family == AF_LINK) sdl = satosdl_c(ifa->ifa_addr); else sdl = NULL; if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0 && !args->namesonly) continue; if (isnametoolong(ifa->ifa_name)) { warnx("%s: interface name too long, skipping", ifa->ifa_name); continue; } cp = ifa->ifa_name; if (!match_if_flags(args, ifa->ifa_flags)) continue; if (!group_member(ifa->ifa_name, args->matchgroup, args->nogroup)) continue; ctx->ifname = cp; /* * Are we just listing the interfaces? */ if (args->namesonly) { if (namecp == cp) continue; if (!match_afp(args->afp, ifa->ifa_addr->sa_family, sdl)) continue; namecp = cp; ifindex++; if (ifindex > 1) printf(" "); fputs(cp, stdout); continue; } ifindex++; if (args->argc > 0) ifconfig(ctx, 0, args->afp); else status(ctx, sdl, ifa); } if (args->namesonly) printf("\n"); freeifaddrs(ifap); } #endif /* * Returns true if an interface should be listed because any its groups * matches shell pattern "match" and none of groups matches pattern "nomatch". * If any pattern is NULL, corresponding condition is skipped. */ bool group_member(const char *ifname, const char *match, const char *nomatch) { static int sock = -1; struct ifgroupreq ifgr; struct ifg_req *ifg; unsigned int len; bool matched, nomatched; /* Sanity checks. */ if (match == NULL && nomatch == NULL) return (true); if (ifname == NULL) return (false); memset(&ifgr, 0, sizeof(ifgr)); strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ); /* The socket is opened once. Let _exit() close it. */ if (sock == -1) { sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) errx(1, "%s: socket(AF_LOCAL,SOCK_DGRAM)", __func__); } /* Determine amount of memory for the list of groups. */ if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { if (errno == EINVAL || errno == ENOTTY) return (false); else errx(1, "%s: SIOCGIFGROUP", __func__); } /* Obtain the list of groups. */ len = ifgr.ifgr_len; ifgr.ifgr_groups = (struct ifg_req *)calloc(len / sizeof(*ifg), sizeof(*ifg)); if (ifgr.ifgr_groups == NULL) errx(1, "%s: no memory", __func__); if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) errx(1, "%s: SIOCGIFGROUP", __func__); /* Perform matching. */ matched = false; nomatched = true; for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(*ifg); ifg++) { len -= sizeof(*ifg); if (match && !matched) matched = !fnmatch(match, ifg->ifgrq_group, 0); if (nomatch && nomatched) nomatched = fnmatch(nomatch, ifg->ifgrq_group, 0); } free(ifgr.ifgr_groups); if (match && !nomatch) return (matched); if (!match && nomatch) return (nomatched); return (matched && nomatched); } static struct afswtch *afs = NULL; void af_register(struct afswtch *p) { p->af_next = afs; afs = p; } static struct afswtch * af_getbyname(const char *name) { struct afswtch *afp; for (afp = afs; afp != NULL; afp = afp->af_next) if (strcmp(afp->af_name, name) == 0) return afp; return NULL; } struct afswtch * af_getbyfamily(int af) { struct afswtch *afp; for (afp = afs; afp != NULL; afp = afp->af_next) if (afp->af_af == af) return afp; return NULL; } void af_other_status(if_ctx *ctx) { struct afswtch *afp; uint8_t afmask[howmany(AF_MAX, NBBY)]; memset(afmask, 0, sizeof(afmask)); for (afp = afs; afp != NULL; afp = afp->af_next) { if (afp->af_other_status == NULL) continue; if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) continue; afp->af_other_status(ctx); setbit(afmask, afp->af_af); } } static void af_all_tunnel_status(if_ctx *ctx) { struct afswtch *afp; uint8_t afmask[howmany(AF_MAX, NBBY)]; memset(afmask, 0, sizeof(afmask)); for (afp = afs; afp != NULL; afp = afp->af_next) { if (afp->af_status_tunnel == NULL) continue; if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) continue; afp->af_status_tunnel(ctx); setbit(afmask, afp->af_af); } } static struct cmd *cmds = NULL; void cmd_register(struct cmd *p) { p->c_next = cmds; cmds = p; } static const struct cmd * cmd_lookup(const char *name, int iscreate) { const struct cmd *p; for (p = cmds; p != NULL; p = p->c_next) if (strcmp(name, p->c_name) == 0) { if (iscreate) { if (p->c_iscloneop) return p; } else { if (!p->c_iscloneop) return p; } } return NULL; } struct callback { callback_func *cb_func; void *cb_arg; struct callback *cb_next; }; static struct callback *callbacks = NULL; void callback_register(callback_func *func, void *arg) { struct callback *cb; cb = malloc(sizeof(struct callback)); if (cb == NULL) errx(1, "unable to allocate memory for callback"); cb->cb_func = func; cb->cb_arg = arg; cb->cb_next = callbacks; callbacks = cb; } /* specially-handled commands */ static void setifaddr(if_ctx *ctx, const char *addr, int param); static const struct cmd setifaddr_cmd = DEF_CMD("ifaddr", 0, setifaddr); static void setifdstaddr(if_ctx *ctx, const char *addr, int param __unused); static const struct cmd setifdstaddr_cmd = DEF_CMD("ifdstaddr", 0, setifdstaddr); int af_exec_ioctl(if_ctx *ctx, unsigned long action, void *data) { struct ifreq *req = (struct ifreq *)data; strlcpy(req->ifr_name, ctx->ifname, sizeof(req->ifr_name)); if (ioctl_ctx(ctx, action, req) == 0) return (0); return (errno); } static void delifaddr(if_ctx *ctx, const struct afswtch *afp) { int error; if (afp->af_exec == NULL) { warnx("interface %s cannot change %s addresses!", ctx->ifname, afp->af_name); clearaddr = 0; return; } error = afp->af_exec(ctx, afp->af_difaddr, afp->af_ridreq); if (error != 0) { if (error == EADDRNOTAVAIL && (doalias >= 0)) { /* means no previous address for interface */ } else Perrorc("ioctl (SIOCDIFADDR)", error); } } static void addifaddr(if_ctx *ctx, const struct afswtch *afp) { if (afp->af_exec == NULL) { warnx("interface %s cannot change %s addresses!", ctx->ifname, afp->af_name); newaddr = 0; return; } if (setaddr || setmask) { int error = afp->af_exec(ctx, afp->af_aifaddr, afp->af_addreq); if (error != 0) Perrorc("ioctl (SIOCAIFADDR)", error); } } int ifconfig_ioctl(if_ctx *orig_ctx, int iscreate, const struct afswtch *uafp) { const struct afswtch *afp, *nafp; const struct cmd *p; struct callback *cb; int s; int argc = orig_ctx->args->argc; char *const *argv = orig_ctx->args->argv; struct ifconfig_context _ctx = { .args = orig_ctx->args, .io_ss = orig_ctx->io_ss, .ifname = orig_ctx->ifname, }; struct ifconfig_context *ctx = &_ctx; struct ifreq ifr = {}; strlcpy(ifr.ifr_name, ctx->ifname, sizeof ifr.ifr_name); afp = NULL; if (uafp != NULL) afp = uafp; /* * This is the historical "accident" allowing users to configure IPv4 * addresses without the "inet" keyword which while a nice feature has * proven to complicate other things. We cannot remove this but only * make sure we will never have a similar implicit default for IPv6 or * any other address familiy. We need a fallback though for * ifconfig IF up/down etc. to work without INET support as people * never used ifconfig IF link up/down, etc. either. */ #ifndef RESCUE #ifdef INET if (afp == NULL && feature_present("inet")) afp = af_getbyname("inet"); #endif #endif if (afp == NULL) afp = af_getbyname("link"); if (afp == NULL) { warnx("Please specify an address_family."); usage(); } top: ifr.ifr_addr.sa_family = afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ? AF_LOCAL : afp->af_af; if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0 && (uafp != NULL || errno != EAFNOSUPPORT || (s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)) err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); ctx->io_s = s; ctx->afp = afp; while (argc > 0) { p = cmd_lookup(*argv, iscreate); if (iscreate && p == NULL) { /* * Push the clone create callback so the new * device is created and can be used for any * remaining arguments. */ cb = callbacks; if (cb == NULL) errx(1, "internal error, no callback"); callbacks = cb->cb_next; cb->cb_func(ctx, cb->cb_arg); iscreate = 0; /* * Handle any address family spec that * immediately follows and potentially * recreate the socket. */ nafp = af_getbyname(*argv); if (nafp != NULL) { argc--, argv++; if (nafp != afp) { close(s); afp = nafp; goto top; } } /* * Look for a normal parameter. */ continue; } if (p == NULL) { /* * Not a recognized command, choose between setting * the interface address and the dst address. */ p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd); } if (p->c_parameter == NEXTARG && p->c_u.c_func) { if (argv[1] == NULL) errx(1, "'%s' requires argument", p->c_name); p->c_u.c_func(ctx, argv[1], 0); argc--, argv++; } else if (p->c_parameter == OPTARG && p->c_u.c_func) { p->c_u.c_func(ctx, argv[1], 0); if (argv[1] != NULL) argc--, argv++; } else if (p->c_parameter == NEXTARG2 && p->c_u.c_func2) { if (argc < 3) errx(1, "'%s' requires 2 arguments", p->c_name); p->c_u.c_func2(ctx, argv[1], argv[2]); argc -= 2, argv += 2; } else if (p->c_parameter == SPARAM && p->c_u.c_func3) { p->c_u.c_func3(ctx, *argv, p->c_sparameter); } else if (p->c_u.c_func) p->c_u.c_func(ctx, *argv, p->c_parameter); argc--, argv++; } /* * Do any post argument processing required by the address family. */ if (afp->af_postproc != NULL) afp->af_postproc(ctx, newaddr, getifflags(ctx->ifname, s, true)); /* * Do deferred callbacks registered while processing * command-line arguments. */ for (cb = callbacks; cb != NULL; cb = cb->cb_next) cb->cb_func(ctx, cb->cb_arg); /* * Do deferred operations. */ if (clearaddr) delifaddr(ctx, afp); if (newaddr) addifaddr(ctx, afp); close(s); return(0); } static void setifaddr(if_ctx *ctx, const char *addr, int param __unused) { const struct afswtch *afp = ctx->afp; if (afp->af_getaddr == NULL) return; /* * Delay the ioctl to set the interface addr until flags are all set. * The address interpretation may depend on the flags, * and the flags may change when the address is set. */ setaddr++; if (doalias == 0 && afp->af_af != AF_LINK) clearaddr = 1; afp->af_getaddr(addr, (doalias >= 0 ? ADDR : RIDADDR)); } static void settunnel(if_ctx *ctx, const char *src, const char *dst) { const struct afswtch *afp = ctx->afp; struct addrinfo *srcres, *dstres; int ecode; if (afp->af_settunnel == NULL) { warn("address family %s does not support tunnel setup", afp->af_name); return; } if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) errx(1, "error in parsing address string: %s", gai_strerror(ecode)); if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) errx(1, "error in parsing address string: %s", gai_strerror(ecode)); if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family) errx(1, "source and destination address families do not match"); afp->af_settunnel(ctx, srcres, dstres); freeaddrinfo(srcres); freeaddrinfo(dstres); } static void deletetunnel(if_ctx *ctx, const char *vname __unused, int param __unused) { struct ifreq ifr = {}; if (ioctl_ctx_ifr(ctx, SIOCDIFPHYADDR, &ifr) < 0) err(1, "SIOCDIFPHYADDR"); } #ifdef JAIL static void setifvnet(if_ctx *ctx, const char *jname, int dummy __unused) { struct ifreq ifr = {}; ifr.ifr_jid = jail_getid(jname); if (ifr.ifr_jid < 0) errx(1, "%s", jail_errmsg); if (ioctl_ctx_ifr(ctx, SIOCSIFVNET, &ifr) < 0) err(1, "SIOCSIFVNET"); } static void setifrvnet(if_ctx *ctx, const char *jname, int dummy __unused) { struct ifreq ifr = {}; ifr.ifr_jid = jail_getid(jname); if (ifr.ifr_jid < 0) errx(1, "%s", jail_errmsg); if (ioctl_ctx_ifr(ctx, SIOCSIFRVNET, &ifr) < 0) err(1, "SIOCSIFRVNET(%d, %s)", ifr.ifr_jid, ifr.ifr_name); } #endif static void setifnetmask(if_ctx *ctx, const char *addr, int dummy __unused) { const struct afswtch *afp = ctx->afp; if (afp->af_getaddr != NULL) { setmask++; afp->af_getaddr(addr, MASK); } } static void setifbroadaddr(if_ctx *ctx, const char *addr, int dummy __unused) { const struct afswtch *afp = ctx->afp; if (afp->af_getaddr != NULL) afp->af_getaddr(addr, BRDADDR); } static void notealias(if_ctx *ctx, const char *addr __unused, int param) { const struct afswtch *afp = ctx->afp; if (setaddr && doalias == 0 && param < 0) { if (afp->af_copyaddr != NULL) afp->af_copyaddr(ctx, RIDADDR, ADDR); } doalias = param; if (param < 0) { clearaddr = 1; newaddr = 0; } else clearaddr = 0; } static void setifdstaddr(if_ctx *ctx, const char *addr, int param __unused) { const struct afswtch *afp = ctx->afp; if (afp->af_getaddr != NULL) afp->af_getaddr(addr, DSTADDR); } static int getifflags(const char *ifname, int us, bool err_ok) { struct ifreq my_ifr; int s; memset(&my_ifr, 0, sizeof(my_ifr)); (void) strlcpy(my_ifr.ifr_name, ifname, sizeof(my_ifr.ifr_name)); if (us < 0) { if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) err(1, "socket(family AF_LOCAL,SOCK_DGRAM"); } else s = us; if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { if (!err_ok) { Perror("ioctl (SIOCGIFFLAGS)"); exit(1); } } if (us < 0) close(s); return ((my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16)); } /* * Note: doing an SIOCIGIFFLAGS scribbles on the union portion * of the ifreq structure, which may confuse other parts of ifconfig. * Make a private copy so we can avoid that. */ static void clearifflags(if_ctx *ctx, const char *vname, int value) { struct ifreq my_ifr; int flags; flags = getifflags(ctx->ifname, ctx->io_s, false); flags &= ~value; memset(&my_ifr, 0, sizeof(my_ifr)); strlcpy(my_ifr.ifr_name, ctx->ifname, sizeof(my_ifr.ifr_name)); my_ifr.ifr_flags = flags & 0xffff; my_ifr.ifr_flagshigh = flags >> 16; if (ioctl(ctx->io_s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0) Perror(vname); } static void setifflags(if_ctx *ctx, const char *vname, int value) { struct ifreq my_ifr; int flags; flags = getifflags(ctx->ifname, ctx->io_s, false); flags |= value; memset(&my_ifr, 0, sizeof(my_ifr)); strlcpy(my_ifr.ifr_name, ctx->ifname, sizeof(my_ifr.ifr_name)); my_ifr.ifr_flags = flags & 0xffff; my_ifr.ifr_flagshigh = flags >> 16; if (ioctl(ctx->io_s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0) Perror(vname); } void clearifcap(if_ctx *ctx, const char *vname, int value) { struct ifreq ifr = {}; int flags; if (ioctl_ctx_ifr(ctx, SIOCGIFCAP, &ifr) < 0) { Perror("ioctl (SIOCGIFCAP)"); exit(1); } flags = ifr.ifr_curcap; flags &= ~value; flags &= ifr.ifr_reqcap; /* Check for no change in capabilities. */ if (ifr.ifr_curcap == flags) return; ifr.ifr_reqcap = flags; if (ioctl_ctx(ctx, SIOCSIFCAP, &ifr) < 0) Perror(vname); } void setifcap(if_ctx *ctx, const char *vname, int value) { struct ifreq ifr = {}; int flags; if (ioctl_ctx_ifr(ctx, SIOCGIFCAP, &ifr) < 0) { Perror("ioctl (SIOCGIFCAP)"); exit(1); } flags = ifr.ifr_curcap; flags |= value; flags &= ifr.ifr_reqcap; /* Check for no change in capabilities. */ if (ifr.ifr_curcap == flags) return; ifr.ifr_reqcap = flags; if (ioctl_ctx(ctx, SIOCSIFCAP, &ifr) < 0) Perror(vname); } void setifcapnv(if_ctx *ctx, const char *vname, const char *arg) { nvlist_t *nvcap; void *buf; char *marg, *mopt; size_t nvbuflen; bool neg; struct ifreq ifr = {}; if (ioctl_ctx_ifr(ctx, SIOCGIFCAP, &ifr) < 0) Perror("ioctl (SIOCGIFCAP)"); if ((ifr.ifr_curcap & IFCAP_NV) == 0) { warnx("IFCAP_NV not supported"); return; /* Not exit() */ } marg = strdup(arg); if (marg == NULL) Perror("strdup"); nvcap = nvlist_create(0); if (nvcap == NULL) Perror("nvlist_create"); while ((mopt = strsep(&marg, ",")) != NULL) { neg = *mopt == '-'; if (neg) mopt++; if (strcmp(mopt, "rxtls") == 0) { nvlist_add_bool(nvcap, "rxtls4", !neg); nvlist_add_bool(nvcap, "rxtls6", !neg); } else { nvlist_add_bool(nvcap, mopt, !neg); } } buf = nvlist_pack(nvcap, &nvbuflen); if (buf == NULL) { errx(1, "nvlist_pack error"); exit(1); } ifr.ifr_cap_nv.buf_length = ifr.ifr_cap_nv.length = nvbuflen; ifr.ifr_cap_nv.buffer = buf; if (ioctl_ctx(ctx, SIOCSIFCAPNV, (caddr_t)&ifr) < 0) Perror(vname); free(buf); nvlist_destroy(nvcap); free(marg); } static void setifmetric(if_ctx *ctx, const char *val, int dummy __unused) { struct ifreq ifr = {}; ifr.ifr_metric = atoi(val); if (ioctl_ctx_ifr(ctx, SIOCSIFMETRIC, &ifr) < 0) err(1, "ioctl SIOCSIFMETRIC (set metric)"); } static void setifmtu(if_ctx *ctx, const char *val, int dummy __unused) { struct ifreq ifr = {}; ifr.ifr_mtu = atoi(val); if (ioctl_ctx_ifr(ctx, SIOCSIFMTU, &ifr) < 0) err(1, "ioctl SIOCSIFMTU (set mtu)"); } static void setifpcp(if_ctx *ctx, const char *val, int arg __unused) { struct ifreq ifr = {}; u_long ul; char *endp; ul = strtoul(val, &endp, 0); if (*endp != '\0') errx(1, "invalid value for pcp"); if (ul > 7) errx(1, "value for pcp out of range"); ifr.ifr_lan_pcp = ul; if (ioctl_ctx_ifr(ctx, SIOCSLANPCP, &ifr) == -1) err(1, "SIOCSLANPCP"); } static void disableifpcp(if_ctx *ctx, const char *val __unused, int arg __unused) { struct ifreq ifr = {}; ifr.ifr_lan_pcp = IFNET_PCP_NONE; if (ioctl_ctx_ifr(ctx, SIOCSLANPCP, &ifr) == -1) err(1, "SIOCSLANPCP"); } static void setifname(if_ctx *ctx, const char *val, int dummy __unused) { struct ifreq ifr = {}; char *newname; ifr_set_name(&ifr, ctx->ifname); newname = strdup(val); if (newname == NULL) err(1, "no memory to set ifname"); ifr.ifr_data = newname; if (ioctl_ctx(ctx, SIOCSIFNAME, (caddr_t)&ifr) < 0) { free(newname); err(1, "ioctl SIOCSIFNAME (set name)"); } ifname_update(ctx, newname); free(newname); } static void setifdescr(if_ctx *ctx, const char *val, int dummy __unused) { struct ifreq ifr = {}; char *newdescr; ifr.ifr_buffer.length = strlen(val) + 1; if (ifr.ifr_buffer.length == 1) { ifr.ifr_buffer.buffer = newdescr = NULL; ifr.ifr_buffer.length = 0; } else { newdescr = strdup(val); ifr.ifr_buffer.buffer = newdescr; if (newdescr == NULL) { warn("no memory to set ifdescr"); return; } } if (ioctl_ctx_ifr(ctx, SIOCSIFDESCR, &ifr) < 0) err(1, "ioctl SIOCSIFDESCR (set descr)"); free(newdescr); } static void unsetifdescr(if_ctx *ctx, const char *val __unused, int value __unused) { setifdescr(ctx, "", 0); } #ifdef WITHOUT_NETLINK #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \ "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ "\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP\25STICKYARP" #define IFCAPBITS \ "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \ "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \ "\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \ "\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP\33NOMAP\34TXTLS4\35TXTLS6" \ "\36VXLAN_HWCSUM\37VXLAN_HWTSO\40TXTLS_RTLMT" static void print_ifcap_nv(if_ctx *ctx) { struct ifreq ifr = {}; nvlist_t *nvcap; const char *nvname; void *buf, *cookie; bool first, val; int type; buf = malloc(IFR_CAP_NV_MAXBUFSIZE); if (buf == NULL) Perror("malloc"); ifr.ifr_cap_nv.buffer = buf; ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE; if (ioctl_ctx_ifr(ctx, SIOCGIFCAPNV, &ifr) != 0) Perror("ioctl (SIOCGIFCAPNV)"); nvcap = nvlist_unpack(ifr.ifr_cap_nv.buffer, ifr.ifr_cap_nv.length, 0); if (nvcap == NULL) Perror("nvlist_unpack"); printf("\toptions"); cookie = NULL; for (first = true;; first = false) { nvname = nvlist_next(nvcap, &type, &cookie); if (nvname == NULL) { printf("\n"); break; } if (type == NV_TYPE_BOOL) { val = nvlist_get_bool(nvcap, nvname); if (val) { printf("%c%s", first ? ' ' : ',', nvname); } } } if (ctx->args->supmedia) { printf("\tcapabilities"); cookie = NULL; for (first = true;; first = false) { nvname = nvlist_next(nvcap, &type, &cookie); if (nvname == NULL) { printf("\n"); break; } if (type == NV_TYPE_BOOL) printf("%c%s", first ? ' ' : ',', nvname); } } nvlist_destroy(nvcap); free(buf); if (ioctl_ctx(ctx, SIOCGIFCAP, (caddr_t)&ifr) != 0) Perror("ioctl (SIOCGIFCAP)"); } static void print_ifcap(if_ctx *ctx) { struct ifreq ifr = {}; if (ioctl_ctx_ifr(ctx, SIOCGIFCAP, &ifr) != 0) return; if ((ifr.ifr_curcap & IFCAP_NV) != 0) print_ifcap_nv(ctx); else { printb("\toptions", ifr.ifr_curcap, IFCAPBITS); putchar('\n'); if (ctx->args->supmedia && ifr.ifr_reqcap != 0) { printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS); putchar('\n'); } } } #endif void print_ifstatus(if_ctx *ctx) { struct ifstat ifs; strlcpy(ifs.ifs_name, ctx->ifname, sizeof ifs.ifs_name); if (ioctl_ctx(ctx, SIOCGIFSTATUS, &ifs) == 0) printf("%s", ifs.ascii); } void print_metric(if_ctx *ctx) { struct ifreq ifr = {}; if (ioctl_ctx_ifr(ctx, SIOCGIFMETRIC, &ifr) != -1) printf(" metric %d", ifr.ifr_metric); } #ifdef WITHOUT_NETLINK static void print_mtu(if_ctx *ctx) { struct ifreq ifr = {}; if (ioctl_ctx_ifr(ctx, SIOCGIFMTU, &ifr) != -1) printf(" mtu %d", ifr.ifr_mtu); } static void print_description(if_ctx *ctx) { struct ifreq ifr = {}; ifr_set_name(&ifr, ctx->ifname); for (;;) { if ((descr = reallocf(descr, descrlen)) != NULL) { ifr.ifr_buffer.buffer = descr; ifr.ifr_buffer.length = descrlen; if (ioctl_ctx(ctx, SIOCGIFDESCR, &ifr) == 0) { if (ifr.ifr_buffer.buffer == descr) { if (strlen(descr) > 0) printf("\tdescription: %s\n", descr); } else if (ifr.ifr_buffer.length > descrlen) { descrlen = ifr.ifr_buffer.length; continue; } } } else warn("unable to allocate memory for interface" "description"); break; } } /* * Print the status of the interface. If an address family was * specified, show only it; otherwise, show them all. */ static void status(if_ctx *ctx, const struct sockaddr_dl *sdl __unused, struct ifaddrs *ifa) { struct ifaddrs *ift; int s, old_s; struct ifconfig_args *args = ctx->args; bool allfamilies = args->afp == NULL; struct ifreq ifr = {}; if (args->afp == NULL) ifr.ifr_addr.sa_family = AF_LOCAL; else ifr.ifr_addr.sa_family = args->afp->af_af == AF_LINK ? AF_LOCAL : args->afp->af_af; s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); if (s < 0) err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); old_s = ctx->io_s; ctx->io_s = s; printf("%s: ", ctx->ifname); printb("flags", ifa->ifa_flags, IFFBITS); print_metric(ctx); print_mtu(ctx); putchar('\n'); print_description(ctx); print_ifcap(ctx); tunnel_status(ctx); for (ift = ifa; ift != NULL; ift = ift->ifa_next) { if (ift->ifa_addr == NULL) continue; if (strcmp(ifa->ifa_name, ift->ifa_name) != 0) continue; if (allfamilies) { const struct afswtch *p; p = af_getbyfamily(ift->ifa_addr->sa_family); if (p != NULL && p->af_status != NULL) p->af_status(ctx, ift); } else if (args->afp->af_af == ift->ifa_addr->sa_family) args->afp->af_status(ctx, ift); } #if 0 if (allfamilies || afp->af_af == AF_LINK) { const struct afswtch *lafp; /* * Hack; the link level address is received separately * from the routing information so any address is not * handled above. Cobble together an entry and invoke * the status method specially. */ lafp = af_getbyname("lladdr"); if (lafp != NULL) { info.rti_info[RTAX_IFA] = (struct sockaddr *)sdl; lafp->af_status(s, &info); } } #endif if (allfamilies) af_other_status(ctx); else if (args->afp->af_other_status != NULL) args->afp->af_other_status(ctx); print_ifstatus(ctx); if (args->verbose > 0) sfp_status(ctx); close(s); ctx->io_s = old_s; return; } #endif void tunnel_status(if_ctx *ctx) { af_all_tunnel_status(ctx); } static void Perrorc(const char *cmd, int error) { switch (errno) { case ENXIO: errx(1, "%s: no such interface", cmd); break; case EPERM: errx(1, "%s: permission denied", cmd); break; default: errc(1, error, "%s", cmd); } } void Perror(const char *cmd) { Perrorc(cmd, errno); } /* * Print a value a la the %b format of the kernel's printf */ void printb(const char *s, unsigned v, const char *bits) { int i, any = 0; char c; if (bits && *bits == 8) printf("%s=%o", s, v); else printf("%s=%x", s, v); if (bits) { bits++; putchar('<'); while ((i = *bits++) != '\0') { if (v & (1u << (i-1))) { if (any) putchar(','); any = 1; for (; (c = *bits) > 32; bits++) putchar(c); } else for (; *bits > 32; bits++) ; } putchar('>'); } } void print_vhid(const struct ifaddrs *ifa) { struct if_data *ifd; if (ifa->ifa_data == NULL) return; ifd = ifa->ifa_data; if (ifd->ifi_vhid == 0) return; printf(" vhid %d", ifd->ifi_vhid); } void ifmaybeload(struct ifconfig_args *args, const char *name) { #define MOD_PREFIX_LEN 3 /* "if_" */ struct module_stat mstat; int fileid, modid; char ifkind[IFNAMSIZ + MOD_PREFIX_LEN], ifname[IFNAMSIZ], *dp; const char *cp; struct module_map_entry *mme; bool found; /* loading suppressed by the user */ if (args->noload) return; /* trim the interface number off the end */ strlcpy(ifname, name, sizeof(ifname)); dp = ifname + strlen(ifname) - 1; for (; dp > ifname; dp--) { if (isdigit(*dp)) *dp = '\0'; else break; } /* Either derive it from the map or guess otherwise */ *ifkind = '\0'; found = false; for (unsigned i = 0; i < nitems(module_map); ++i) { mme = &module_map[i]; if (strcmp(mme->ifname, ifname) == 0) { strlcpy(ifkind, mme->kldname, sizeof(ifkind)); found = true; break; } } /* We didn't have an alias for it... we'll guess. */ if (!found) { /* turn interface and unit into module name */ strlcpy(ifkind, "if_", sizeof(ifkind)); strlcat(ifkind, ifname, sizeof(ifkind)); } /* scan files in kernel */ mstat.version = sizeof(struct module_stat); for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { /* scan modules in file */ for (modid = kldfirstmod(fileid); modid > 0; modid = modfnext(modid)) { if (modstat(modid, &mstat) < 0) continue; /* strip bus name if present */ if ((cp = strchr(mstat.name, '/')) != NULL) { cp++; } else { cp = mstat.name; } /* * Is it already loaded? Don't compare with ifname if * we were specifically told which kld to use. Doing * so could lead to conflicts not trivially solved. */ if ((!found && strcmp(ifname, cp) == 0) || strcmp(ifkind, cp) == 0) return; } } /* * Try to load the module. But ignore failures, because ifconfig can't * infer the names of all drivers (eg mlx4en(4)). */ (void) kldload(ifkind); } static struct cmd basic_cmds[] = { DEF_CMD("up", IFF_UP, setifflags), DEF_CMD("down", IFF_UP, clearifflags), DEF_CMD("arp", IFF_NOARP, clearifflags), DEF_CMD("-arp", IFF_NOARP, setifflags), DEF_CMD("debug", IFF_DEBUG, setifflags), DEF_CMD("-debug", IFF_DEBUG, clearifflags), DEF_CMD_ARG("description", setifdescr), DEF_CMD_ARG("descr", setifdescr), DEF_CMD("-description", 0, unsetifdescr), DEF_CMD("-descr", 0, unsetifdescr), DEF_CMD("promisc", IFF_PPROMISC, setifflags), DEF_CMD("-promisc", IFF_PPROMISC, clearifflags), DEF_CMD("add", IFF_UP, notealias), DEF_CMD("alias", IFF_UP, notealias), DEF_CMD("-alias", -IFF_UP, notealias), DEF_CMD("delete", -IFF_UP, notealias), DEF_CMD("remove", -IFF_UP, notealias), #ifdef notdef #define EN_SWABIPS 0x1000 DEF_CMD("swabips", EN_SWABIPS, setifflags), DEF_CMD("-swabips", EN_SWABIPS, clearifflags), #endif DEF_CMD_ARG("netmask", setifnetmask), DEF_CMD_ARG("metric", setifmetric), DEF_CMD_ARG("broadcast", setifbroadaddr), DEF_CMD_ARG2("tunnel", settunnel), DEF_CMD("-tunnel", 0, deletetunnel), DEF_CMD("deletetunnel", 0, deletetunnel), #ifdef JAIL DEF_CMD_ARG("vnet", setifvnet), DEF_CMD_ARG("-vnet", setifrvnet), #endif DEF_CMD("link0", IFF_LINK0, setifflags), DEF_CMD("-link0", IFF_LINK0, clearifflags), DEF_CMD("link1", IFF_LINK1, setifflags), DEF_CMD("-link1", IFF_LINK1, clearifflags), DEF_CMD("link2", IFF_LINK2, setifflags), DEF_CMD("-link2", IFF_LINK2, clearifflags), DEF_CMD("monitor", IFF_MONITOR, setifflags), DEF_CMD("-monitor", IFF_MONITOR, clearifflags), DEF_CMD("mextpg", IFCAP_MEXTPG, setifcap), DEF_CMD("-mextpg", IFCAP_MEXTPG, clearifcap), DEF_CMD("staticarp", IFF_STATICARP, setifflags), DEF_CMD("-staticarp", IFF_STATICARP, clearifflags), DEF_CMD("stickyarp", IFF_STICKYARP, setifflags), DEF_CMD("-stickyarp", IFF_STICKYARP, clearifflags), DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap), DEF_CMD("-rxcsum6", IFCAP_RXCSUM_IPV6, clearifcap), DEF_CMD("txcsum6", IFCAP_TXCSUM_IPV6, setifcap), DEF_CMD("-txcsum6", IFCAP_TXCSUM_IPV6, clearifcap), DEF_CMD("rxcsum", IFCAP_RXCSUM, setifcap), DEF_CMD("-rxcsum", IFCAP_RXCSUM, clearifcap), DEF_CMD("txcsum", IFCAP_TXCSUM, setifcap), DEF_CMD("-txcsum", IFCAP_TXCSUM, clearifcap), DEF_CMD("netcons", IFCAP_NETCONS, setifcap), DEF_CMD("-netcons", IFCAP_NETCONS, clearifcap), DEF_CMD_ARG("pcp", setifpcp), DEF_CMD("-pcp", 0, disableifpcp), DEF_CMD("polling", IFCAP_POLLING, setifcap), DEF_CMD("-polling", IFCAP_POLLING, clearifcap), DEF_CMD("tso6", IFCAP_TSO6, setifcap), DEF_CMD("-tso6", IFCAP_TSO6, clearifcap), DEF_CMD("tso4", IFCAP_TSO4, setifcap), DEF_CMD("-tso4", IFCAP_TSO4, clearifcap), DEF_CMD("tso", IFCAP_TSO, setifcap), DEF_CMD("-tso", IFCAP_TSO, clearifcap), DEF_CMD("toe", IFCAP_TOE, setifcap), DEF_CMD("-toe", IFCAP_TOE, clearifcap), DEF_CMD("lro", IFCAP_LRO, setifcap), DEF_CMD("-lro", IFCAP_LRO, clearifcap), DEF_CMD("txtls", IFCAP_TXTLS, setifcap), DEF_CMD("-txtls", IFCAP_TXTLS, clearifcap), DEF_CMD_SARG("rxtls", IFCAP2_RXTLS4_NAME "," IFCAP2_RXTLS6_NAME, setifcapnv), DEF_CMD_SARG("-rxtls", "-"IFCAP2_RXTLS4_NAME ",-" IFCAP2_RXTLS6_NAME, setifcapnv), DEF_CMD("wol", IFCAP_WOL, setifcap), DEF_CMD("-wol", IFCAP_WOL, clearifcap), DEF_CMD("wol_ucast", IFCAP_WOL_UCAST, setifcap), DEF_CMD("-wol_ucast", IFCAP_WOL_UCAST, clearifcap), DEF_CMD("wol_mcast", IFCAP_WOL_MCAST, setifcap), DEF_CMD("-wol_mcast", IFCAP_WOL_MCAST, clearifcap), DEF_CMD("wol_magic", IFCAP_WOL_MAGIC, setifcap), DEF_CMD("-wol_magic", IFCAP_WOL_MAGIC, clearifcap), DEF_CMD("txrtlmt", IFCAP_TXRTLMT, setifcap), DEF_CMD("-txrtlmt", IFCAP_TXRTLMT, clearifcap), DEF_CMD("txtlsrtlmt", IFCAP_TXTLS_RTLMT, setifcap), DEF_CMD("-txtlsrtlmt", IFCAP_TXTLS_RTLMT, clearifcap), DEF_CMD("hwrxtstmp", IFCAP_HWRXTSTMP, setifcap), DEF_CMD("-hwrxtstmp", IFCAP_HWRXTSTMP, clearifcap), DEF_CMD("normal", IFF_LINK0, clearifflags), DEF_CMD("compress", IFF_LINK0, setifflags), DEF_CMD("noicmp", IFF_LINK1, setifflags), DEF_CMD_ARG("mtu", setifmtu), DEF_CMD_ARG("name", setifname), }; static __constructor void ifconfig_ctor(void) { size_t i; for (i = 0; i < nitems(basic_cmds); i++) cmd_register(&basic_cmds[i]); } diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index 3303c4894ba7..76a5aeb718b1 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -1,328 +1,329 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1997 Peter Wemm. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the FreeBSD Project * by Peter Wemm. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * so there! */ #pragma once #include #include #include #define __constructor __attribute__((constructor)) #ifdef WITHOUT_NETLINK #define __netlink_used __unused #define __netlink_unused #else #define __netlink_used #define __netlink_unused __unused #endif struct afswtch; struct cmd; struct snl_state; struct ifconfig_args; struct ifconfig_context { struct ifconfig_args *args; const struct afswtch *afp; int io_s; /* fd to use for ioctl() */ struct snl_state *io_ss; /* NETLINK_ROUTE socket */ const char *ifname; /* Current interface name */ char _ifname_storage_ioctl[IFNAMSIZ]; }; typedef struct ifconfig_context if_ctx; typedef void c_func(if_ctx *ctx, const char *cmd, int arg); typedef void c_func2(if_ctx *ctx, const char *arg1, const char *arg2); typedef void c_func3(if_ctx *ctx, const char *cmd, const char *arg); struct cmd { const char *c_name; int c_parameter; #define NEXTARG 0xffffff /* has following arg */ #define NEXTARG2 0xfffffe /* has 2 following args */ #define OPTARG 0xfffffd /* has optional following arg */ #define SPARAM 0xfffffc /* parameter is string c_sparameter */ const char *c_sparameter; union { c_func *c_func; c_func2 *c_func2; c_func3 *c_func3; } c_u; int c_iscloneop; struct cmd *c_next; }; void cmd_register(struct cmd *); typedef void callback_func(if_ctx *, void *); void callback_register(callback_func *, void *); /* * Macros for initializing command handlers. */ #define DEF_CMD(name, param, func) { \ .c_name = (name), \ .c_parameter = (param), \ .c_u = { .c_func = (func) }, \ .c_iscloneop = 0, \ .c_next = NULL, \ } #define DEF_CMD_ARG(name, func) { \ .c_name = (name), \ .c_parameter = NEXTARG, \ .c_u = { .c_func = (func) }, \ .c_iscloneop = 0, \ .c_next = NULL, \ } #define DEF_CMD_OPTARG(name, func) { \ .c_name = (name), \ .c_parameter = OPTARG, \ .c_u = { .c_func = (func) }, \ .c_iscloneop = 0, \ .c_next = NULL, \ } #define DEF_CMD_ARG2(name, func) { \ .c_name = (name), \ .c_parameter = NEXTARG2, \ .c_u = { .c_func2 = (func) }, \ .c_iscloneop = 0, \ .c_next = NULL, \ } #define DEF_CMD_SARG(name, sparam, func) { \ .c_name = (name), \ .c_parameter = SPARAM, \ .c_sparameter = (sparam), \ .c_u = { .c_func3 = (func) }, \ .c_iscloneop = 0, \ .c_next = NULL, \ } #define DEF_CLONE_CMD(name, param, func) { \ .c_name = (name), \ .c_parameter = (param), \ .c_u = { .c_func = (func) }, \ .c_iscloneop = 1, \ .c_next = NULL, \ } #define DEF_CLONE_CMD_ARG(name, func) { \ .c_name = (name), \ .c_parameter = NEXTARG, \ .c_u = { .c_func = (func) }, \ .c_iscloneop = 1, \ .c_next = NULL, \ } #define DEF_CLONE_CMD_ARG2(name, func) { \ .c_name = (name), \ .c_parameter = NEXTARG2, \ .c_u = { .c_func2 = (func) }, \ .c_iscloneop = 1, \ .c_next = NULL, \ } #define ioctl_ctx(ctx, _req, ...) ioctl((ctx)->io_s, _req, ## __VA_ARGS__) int ioctl_ctx_ifr(if_ctx *ctx, unsigned long cmd, struct ifreq *ifr); struct ifaddrs; struct addrinfo; enum { RIDADDR = 0, ADDR = 1, MASK = 2, DSTADDR = 3, #ifdef WITHOUT_NETLINK BRDADDR = 3, #else BRDADDR = 4, #endif }; struct snl_parsed_addr; struct snl_parsed_link; typedef struct snl_parsed_link if_link_t; typedef struct snl_parsed_addr if_addr_t; typedef void af_setvhid_f(int vhid); typedef void af_status_nl_f(if_ctx *ctx, if_link_t *link, if_addr_t *ifa); typedef void af_status_f(if_ctx *ctx, const struct ifaddrs *); typedef void af_other_status_f(if_ctx *ctx); typedef void af_postproc_f(if_ctx *ctx, int newaddr, int ifflags); typedef int af_exec_f(if_ctx *ctx, unsigned long action, void *data); typedef void af_copyaddr_f(if_ctx *ctx, int to, int from); typedef void af_status_tunnel_f(if_ctx *ctx); typedef void af_settunnel_f(if_ctx *ctx, struct addrinfo *srcres, struct addrinfo *dstres); struct afswtch { const char *af_name; /* as given on cmd line, e.g. "inet" */ short af_af; /* AF_* */ /* * Status is handled one of two ways; if there is an * address associated with the interface then the * associated address family af_status method is invoked * with the appropriate addressin info. Otherwise, if * all possible info is to be displayed and af_other_status * is defined then it is invoked after all address status * is presented. */ #ifndef WITHOUT_NETLINK af_status_nl_f *af_status; #else af_status_f *af_status; #endif af_other_status_f *af_other_status; void (*af_getaddr)(const char *, int); af_copyaddr_f *af_copyaddr; /* Copy address between ADDR */ /* parse prefix method (IPv6) */ void (*af_getprefix)(const char *, int); af_postproc_f *af_postproc; af_setvhid_f *af_setvhid; /* Set CARP vhid for an address */ af_exec_f *af_exec; /* Handler to interact with kernel */ u_long af_difaddr; /* set dst if address ioctl */ u_long af_aifaddr; /* set if address ioctl */ void *af_ridreq; /* */ void *af_addreq; /* */ struct afswtch *af_next; /* XXX doesn't fit model */ af_status_tunnel_f *af_status_tunnel; af_settunnel_f *af_settunnel; }; void af_register(struct afswtch *); int af_exec_ioctl(if_ctx *ctx, unsigned long action, void *data); struct ifconfig_args { bool all; /* Match everything */ bool downonly; /* Down-only items */ bool uponly; /* Up-only items */ bool namesonly; /* Output only names */ bool noload; /* Do not load relevant kernel modules */ bool supmedia; /* Supported media */ bool printkeys; /* Print security keys */ bool allfamilies; /* Print all families */ + bool drivername; /* Print driver name */ int verbose; /* verbosity level */ int argc; char **argv; const char *ifname; /* Requested interface name */ const char *matchgroup; /* Group name to match */ const char *nogroup; /* Group name to exclude */ const struct afswtch *afp; /* AF we're operating on */ const char *jail_name; /* Jail name or jail id specified */ }; struct option { const char *opt; const char *opt_usage; void (*cb)(const char *arg); struct option *next; }; void opt_register(struct option *); extern ifconfig_handle_t *lifh; extern int allmedia; extern int exit_code; extern char *f_inet, *f_inet6, *f_ether, *f_addr; void clearifcap(if_ctx *ctx, const char *, int value); void setifcap(if_ctx *ctx, const char *, int value); void setifcapnv(if_ctx *ctx, const char *vname, const char *arg); void Perror(const char *cmd); void printb(const char *s, unsigned value, const char *bits); void ifmaybeload(struct ifconfig_args *args, const char *name); typedef int clone_match_func(const char *); typedef void clone_callback_func(if_ctx *, struct ifreq *); void clone_setdefcallback_prefix(const char *, clone_callback_func *); void clone_setdefcallback_filter(clone_match_func *, clone_callback_func *); void sfp_status(if_ctx *ctx); struct sockaddr_dl; bool match_ether(const struct sockaddr_dl *sdl); bool match_if_flags(struct ifconfig_args *args, int if_flags); int ifconfig_ioctl(if_ctx *ctx, int iscreate, const struct afswtch *uafp); bool group_member(const char *ifname, const char *match, const char *nomatch); void tunnel_status(if_ctx *ctx); struct afswtch *af_getbyfamily(int af); void af_other_status(if_ctx *ctx); void print_ifstatus(if_ctx *ctx); void print_metric(if_ctx *ctx); ifType convert_iftype(ifType iftype); /* Netlink-related functions */ void list_interfaces_nl(struct ifconfig_args *args); int ifconfig_nl(if_ctx *ctx, int iscreate, const struct afswtch *uafp); uint32_t if_nametoindex_nl(struct snl_state *ss, const char *ifname); /* * XXX expose this so modules that need to know of any pending * operations on ifmedia can avoid cmd line ordering confusion. */ struct ifmediareq *ifmedia_getstate(if_ctx *ctx); void print_vhid(const struct ifaddrs *); void ifcreate_ioctl(if_ctx *ctx, struct ifreq *ifr); /* Helpers */ struct sockaddr_in; struct sockaddr_in6; struct sockaddr; static inline struct sockaddr_in6 * satosin6(struct sockaddr *sa) { return ((struct sockaddr_in6 *)(void *)sa); } static inline struct sockaddr_in * satosin(struct sockaddr *sa) { return ((struct sockaddr_in *)(void *)sa); } static inline struct sockaddr_dl * satosdl(struct sockaddr *sa) { return ((struct sockaddr_dl *)(void *)sa); } static inline const struct sockaddr_dl * satosdl_c(const struct sockaddr *sa) { return ((const struct sockaddr_dl *)(const void *)sa); } diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c index 826d199d3ccb..8964b63caf7b 100644 --- a/sbin/ifconfig/ifconfig_netlink.c +++ b/sbin/ifconfig/ifconfig_netlink.c @@ -1,497 +1,514 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2022 Alexander V. Chernikov * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ifconfig.h" #include "ifconfig_netlink.h" static const char *IFFBITS[] = { "UP", /* 00:0x1 IFF_UP*/ "BROADCAST", /* 01:0x2 IFF_BROADCAST*/ "DEBUG", /* 02:0x4 IFF_DEBUG*/ "LOOPBACK", /* 03:0x8 IFF_LOOPBACK*/ "POINTOPOINT", /* 04:0x10 IFF_POINTOPOINT*/ "NEEDSEPOCH", /* 05:0x20 IFF_NEEDSEPOCH*/ "RUNNING", /* 06:0x40 IFF_DRV_RUNNING*/ "NOARP", /* 07:0x80 IFF_NOARP*/ "PROMISC", /* 08:0x100 IFF_PROMISC*/ "ALLMULTI", /* 09:0x200 IFF_ALLMULTI*/ "DRV_OACTIVE", /* 10:0x400 IFF_DRV_OACTIVE*/ "SIMPLEX", /* 11:0x800 IFF_SIMPLEX*/ "LINK0", /* 12:0x1000 IFF_LINK0*/ "LINK1", /* 13:0x2000 IFF_LINK1*/ "LINK2", /* 14:0x4000 IFF_LINK2*/ "MULTICAST", /* 15:0x8000 IFF_MULTICAST*/ "CANTCONFIG", /* 16:0x10000 IFF_CANTCONFIG*/ "PPROMISC", /* 17:0x20000 IFF_PPROMISC*/ "MONITOR", /* 18:0x40000 IFF_MONITOR*/ "STATICARP", /* 19:0x80000 IFF_STATICARP*/ "STICKYARP", /* 20:0x100000 IFF_STICKYARP*/ "DYING", /* 21:0x200000 IFF_DYING*/ "RENAMING", /* 22:0x400000 IFF_RENAMING*/ "NOGROUP", /* 23:0x800000 IFF_NOGROUP*/ "LOWER_UP", /* 24:0x1000000 IFF_NETLINK_1*/ }; static void print_bits(const char *btype, uint32_t *v, const int v_count, const char **names, const int n_count) { int num = 0; for (int i = 0; i < v_count * 32; i++) { bool is_set = v[i / 32] & (1U << (i % 32)); if (is_set) { if (num++ == 0) printf("<"); if (num != 1) printf(","); if (i < n_count) printf("%s", names[i]); else printf("%s_%d", btype, i); } } if (num > 0) printf(">"); } static void nl_init_socket(struct snl_state *ss) { if (snl_init(ss, NETLINK_ROUTE)) return; if (modfind("netlink") == -1 && errno == ENOENT) { /* Try to load */ if (kldload("netlink") == -1) err(1, "netlink is not loaded and load attempt failed"); if (snl_init(ss, NETLINK_ROUTE)) return; } err(1, "unable to open netlink socket"); } int ifconfig_nl(if_ctx *ctx, int iscreate, const struct afswtch *uafp) { struct snl_state ss = {}; nl_init_socket(&ss); ctx->io_ss = &ss; int error = ifconfig_ioctl(ctx, iscreate, uafp); snl_free(&ss); ctx->io_ss = NULL; return (error); } struct ifa { struct ifa *next; uint32_t idx; struct snl_parsed_addr addr; }; struct iface { struct snl_parsed_link link; struct ifa *ifa; uint32_t ifa_count; uint32_t idx; }; struct ifmap { uint32_t size; uint32_t count; struct iface **ifaces; }; /* * Returns ifmap ifindex->snl_parsed_link. * Memory is allocated using snl temporary buffers */ static struct ifmap * prepare_ifmap(struct snl_state *ss) { struct snl_writer nw = {}; snl_init_writer(ss, &nw); struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETLINK); hdr->nlmsg_flags |= NLM_F_DUMP; snl_reserve_msg_object(&nw, struct ifinfomsg); if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr)) return (NULL); uint32_t nlmsg_seq = hdr->nlmsg_seq; struct ifmap *ifmap = snl_allocz(ss, sizeof(*ifmap)); struct snl_errmsg_data e = {}; while ((hdr = snl_read_reply_multi(ss, nlmsg_seq, &e)) != NULL) { struct iface *iface = snl_allocz(ss, sizeof(*iface)); if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_link_parser, &iface->link)) continue; if (iface->link.ifi_index >= ifmap->size) { size_t new_size = MAX(ifmap->size, 32); while (new_size <= iface->link.ifi_index + 1) new_size *= 2; struct iface **ifaces= snl_allocz(ss, new_size * sizeof(void *)); memcpy(ifaces, ifmap->ifaces, ifmap->size * sizeof(void *)); ifmap->ifaces = ifaces; ifmap->size = new_size; } ifmap->ifaces[iface->link.ifi_index] = iface; ifmap->count++; iface->idx = ifmap->count; } return (ifmap); } uint32_t if_nametoindex_nl(struct snl_state *ss, const char *ifname) { struct snl_writer nw = {}; struct snl_parsed_link_simple link = {}; snl_init_writer(ss, &nw); struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETLINK); snl_reserve_msg_object(&nw, struct ifinfomsg); snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname); if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr)) return (0); hdr = snl_read_reply(ss, hdr->nlmsg_seq); if (hdr->nlmsg_type != NL_RTM_NEWLINK) return (0); if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_link_parser_simple, &link)) return (0); return (link.ifi_index); } ifType convert_iftype(ifType iftype) { switch (iftype) { case IFT_IEEE8023ADLAG: return (IFT_ETHER); case IFT_INFINIBANDLAG: return (IFT_INFINIBAND); default: return (iftype); } } static void prepare_ifaddrs(struct snl_state *ss, struct ifmap *ifmap) { struct snl_writer nw = {}; snl_init_writer(ss, &nw); struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETADDR); hdr->nlmsg_flags |= NLM_F_DUMP; snl_reserve_msg_object(&nw, struct ifaddrmsg); if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr)) return; uint32_t nlmsg_seq = hdr->nlmsg_seq; struct snl_errmsg_data e = {}; uint32_t count = 0; while ((hdr = snl_read_reply_multi(ss, nlmsg_seq, &e)) != NULL) { struct ifa *ifa = snl_allocz(ss, sizeof(*ifa)); if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_addr_parser, &ifa->addr)) continue; const uint32_t ifindex = ifa->addr.ifa_index; if (ifindex >= ifmap->size || ifmap->ifaces[ifindex] == NULL) continue; struct iface *iface = ifmap->ifaces[ifindex]; ifa->next = iface->ifa; ifa->idx = ++count; iface->ifa = ifa; iface->ifa_count++; } } static bool match_iface(struct ifconfig_args *args, struct iface *iface) { if_link_t *link = &iface->link; if (args->ifname != NULL && strcmp(args->ifname, link->ifla_ifname)) return (false); if (!match_if_flags(args, link->ifi_flags)) return (false); if (!group_member(link->ifla_ifname, args->matchgroup, args->nogroup)) return (false); if (args->afp == NULL) return (true); if (!strcmp(args->afp->af_name, "ether")) { if (link->ifla_address == NULL) return (false); struct sockaddr_dl sdl = { .sdl_len = sizeof(struct sockaddr_dl), .sdl_family = AF_LINK, .sdl_type = convert_iftype(link->ifi_type), .sdl_alen = NLA_DATA_LEN(link->ifla_address), }; return (match_ether(&sdl)); } else if (args->afp->af_af == AF_LINK) /* * The rtnetlink(4) RTM_GETADDR does not list link level * addresses, so latter cycle won't match anything. Short * circuit on RTM_GETLINK has provided us an address. */ return (link->ifla_address != NULL); for (struct ifa *ifa = iface->ifa; ifa != NULL; ifa = ifa->next) { if (args->afp->af_af == ifa->addr.ifa_family) return (true); } return (false); } /* Sort according to the kernel-provided order */ static int cmp_iface(const void *_a, const void *_b) { const struct iface *a = *((const void * const *)_a); const struct iface *b = *((const void * const *)_b); return ((a->idx > b->idx) * 2 - 1); } static int cmp_ifaddr(const void *_a, const void *_b) { const struct ifa *a = *((const void * const *)_a); const struct ifa *b = *((const void * const *)_b); if (a->addr.ifa_family != b->addr.ifa_family) return ((a->addr.ifa_family > b->addr.ifa_family) * 2 - 1); return ((a->idx > b->idx) * 2 - 1); } static void sort_iface_ifaddrs(struct snl_state *ss, struct iface *iface) { if (iface->ifa_count == 0) return; struct ifa **sorted_ifaddrs = snl_allocz(ss, iface->ifa_count * sizeof(void *)); struct ifa *ifa = iface->ifa; for (uint32_t i = 0; i < iface->ifa_count; i++) { struct ifa *ifa_next = ifa->next; sorted_ifaddrs[i] = ifa; ifa->next = NULL; ifa = ifa_next; } qsort(sorted_ifaddrs, iface->ifa_count, sizeof(void *), cmp_ifaddr); ifa = sorted_ifaddrs[0]; iface->ifa = ifa; for (uint32_t i = 1; i < iface->ifa_count; i++) { ifa->next = sorted_ifaddrs[i]; ifa = sorted_ifaddrs[i]; } } static void print_ifcaps(if_ctx *ctx, if_link_t *link) { uint32_t sz_u32 = roundup2(link->iflaf_caps.nla_bitset_size, 32) / 32; if (sz_u32 > 0) { uint32_t *caps = link->iflaf_caps.nla_bitset_value; printf("\toptions=%x", caps[0]); print_bits("IFCAPS", caps, sz_u32, ifcap_bit_names, nitems(ifcap_bit_names)); putchar('\n'); } if (ctx->args->supmedia && sz_u32 > 0) { uint32_t *caps = link->iflaf_caps.nla_bitset_mask; printf("\tcapabilities=%x", caps[0]); print_bits("IFCAPS", caps, sz_u32, ifcap_bit_names, nitems(ifcap_bit_names)); putchar('\n'); } } static void status_nl(if_ctx *ctx, struct iface *iface) { if_link_t *link = &iface->link; struct ifconfig_args *args = ctx->args; + char *drivername = NULL; printf("%s: ", link->ifla_ifname); printf("flags=%x", link->ifi_flags); print_bits("IFF", &link->ifi_flags, 1, IFFBITS, nitems(IFFBITS)); print_metric(ctx); printf(" mtu %d\n", link->ifla_mtu); if (link->ifla_ifalias != NULL) printf("\tdescription: %s\n", link->ifla_ifalias); print_ifcaps(ctx, link); tunnel_status(ctx); if (args->allfamilies | (args->afp != NULL && args->afp->af_af == AF_LINK)) { /* Start with link-level */ const struct afswtch *p = af_getbyfamily(AF_LINK); if (p != NULL && link->ifla_address != NULL) p->af_status(ctx, link, NULL); } sort_iface_ifaddrs(ctx->io_ss, iface); for (struct ifa *ifa = iface->ifa; ifa != NULL; ifa = ifa->next) { if (args->allfamilies) { const struct afswtch *p = af_getbyfamily(ifa->addr.ifa_family); if (p != NULL) p->af_status(ctx, link, &ifa->addr); } else if (args->afp->af_af == ifa->addr.ifa_family) { const struct afswtch *p = args->afp; p->af_status(ctx, link, &ifa->addr); } } /* TODO: convert to netlink */ if (args->allfamilies) af_other_status(ctx); else if (args->afp->af_other_status != NULL) args->afp->af_other_status(ctx); print_ifstatus(ctx); + if (args->drivername || args->verbose) { + if (ifconfig_get_orig_name(lifh, link->ifla_ifname, + &drivername) != 0) { + if (ifconfig_err_errtype(lifh) == OTHER) + fprintf(stderr, "get original name: %s\n", + strerror(ifconfig_err_errno(lifh))); + else + fprintf(stderr, + "get original name: error type %d\n", + ifconfig_err_errtype(lifh)); + exit_code = 1; + } + if (drivername != NULL) + printf("\tdrivername: %s\n", drivername); + free(drivername); + } if (args->verbose > 0) sfp_status(ctx); } static int get_local_socket(void) { int s = socket(AF_LOCAL, SOCK_DGRAM, 0); if (s < 0) err(1, "socket(family %u,SOCK_DGRAM)", AF_LOCAL); return (s); } void list_interfaces_nl(struct ifconfig_args *args) { struct snl_state ss = {}; struct ifconfig_context _ctx = { .args = args, .io_s = get_local_socket(), .io_ss = &ss, }; struct ifconfig_context *ctx = &_ctx; nl_init_socket(&ss); struct ifmap *ifmap = prepare_ifmap(&ss); struct iface **sorted_ifaces = snl_allocz(&ss, ifmap->count * sizeof(void *)); for (uint32_t i = 0, num = 0; i < ifmap->size; i++) { if (ifmap->ifaces[i] != NULL) { sorted_ifaces[num++] = ifmap->ifaces[i]; if (num == ifmap->count) break; } } qsort(sorted_ifaces, ifmap->count, sizeof(void *), cmp_iface); prepare_ifaddrs(&ss, ifmap); for (uint32_t i = 0, num = 0; i < ifmap->count; i++) { struct iface *iface = sorted_ifaces[i]; if (!match_iface(args, iface)) continue; ctx->ifname = iface->link.ifla_ifname; if (args->namesonly) { if (num++ != 0) printf(" "); fputs(iface->link.ifla_ifname, stdout); } else if (args->argc == 0) status_nl(ctx, iface); else ifconfig_ioctl(ctx, 0, args->afp); } if (args->namesonly) printf("\n"); close(ctx->io_s); snl_free(&ss); }