the command 'ifconfig epair2a link 10.1.2.200/28' has a somewhat
surprising result:
% ifconfig epair2a link 10.1.2.200/28
% ifconfig epair2a
epair2a: flags=1008842<BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=8<VLAN_MTU> ether 10:01:02:20:00:28 hwaddr 02:25:24:d4:38:0a
this is because link_addr(3) considers any unrecognised character, such
as '.' or '/', to be a delimiter in the Ethernet address. usually this
wouldn't be a significant problem, because people should just not do
this.
however, consider a system which is IPv6-only, i.e., the kernel supports
INET6 but not INET. in this case ifconfig(8) defaults to the 'link'
address family instead of the 'inet' address family. then suppose the
user has an existing ifconfig_xxx entry in /etc/rc.conf:
ifconfig_hn0="10.1.2.200/28"
because ifconfig defaults to 'link', two things will occur:
- ifconfig will silently accept the IP address as an Ethernet address.
- ifconfig will change the Ethernet address of the interface, causing all networking (including IPv6) to break.
to fix this, change link_addr() to return an int (instead of void), and
return -1 if it detects characters other than '.' or ':' used as
delimiters. this preserves support common Ethernet address syntaxes,
but prevents accepting an IP address with a netmask as a link address.
bump __FreeBSD_version so link_addr() consumers can detect the change.