590493c1:

if_epair(4): use ether_gen_addr(9) for stable MAC address

Before this change epair interfaces get a random MAC. This does
not help dhcp/dyndns when an epair gets destroyed/recreated
after restart of a jail.

With this change:
$ sysctl net.link.epair.ether_gen_addr=0
$ ifconfig epair8 create > /dev/null; ifconfig epair8a | grep ether; ifconfig epair8b | grep ether; ifconfig epair8a destroy
	ether 02:cb:78:56:e4:0a
	ether 02:cb:78:56:e4:0b
$ ifconfig epair8 create > /dev/null; ifconfig epair8a | grep ether; ifconfig epair8b | grep ether; ifconfig epair8a destroy
	ether 02:8b:9b:6a:8f:0a
	ether 02:8b:9b:6a:8f:0b

$ sysctl net.link.epair.ether_gen_addr=1
$ ifconfig epair8 create > /dev/null; ifconfig epair8a | grep ether; ifconfig epair8b | grep ether; ifconfig epair8a destroy
	ether 58:9c:fc:10:2b:b4
	ether 58:9c:fc:00:39:10
$ ifconfig epair8 create > /dev/null; ifconfig epair8a | grep ether; ifconfig epair8b | grep ether; ifconfig epair8a destroy
	ether 58:9c:fc:10:2b:b4
	ether 58:9c:fc:00:39:10

A follow up commit will change the default to 1 in main.

Approved by:	bz,ivy,kp
Relnotes:	yes
Differential Revision: https://reviews.freebsd.org/D51157

78537728:
Document tunable net.link.epair.ether_gen_addr

Approved by:	hrs
Fixes:	590493c1419092e98f7ad1dcadb886973502341e ("if_epair(4): use ether_gen_addr(9) for stable MAC address")
Differential Revision: https://reviews.freebsd.org/D51861

(cherry picked from commit 590493c1419092e98f7ad1dcadb886973502341e)
(cherry picked from commit 78537728efc5387558c97ba2730ce746d6259013)
This commit is contained in:
Ronald Klop 2025-07-03 18:33:03 +02:00 committed by Franco Fichtner
parent 7e2e14fc22
commit 2d705b23bf
2 changed files with 48 additions and 9 deletions

View file

@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd March 18, 2015
.Dd August 12, 2025
.Dt EPAIR 4
.Os
.Sh NAME
@ -79,12 +79,24 @@ and
Like any other Ethernet interface, an
.Nm
needs to have a network address.
Each
If the tunable
.Va net.link.epair.ether_gen_addr Ns
=0, each
.Nm
will be assigned a locally administered address by default,
will be assigned a random locally administered address,
that is only guaranteed to be unique within one network stack.
To change the default addresses one may use the SIOCSIFADDR ioctl(2) or
ifconfig(8) utility.
The tunable
.Va net.link.epair.ether_gen_addr Ns
=1 will generate a stable MAC address with
.Fx
OUI using
.Xr ether_gen_addr 9 .
This tunable defaults to 1 in
.Fx 15.0 and might be removed in
.Fx 16.0 .
To change the default addresses one may use the SIOCSIFADDR
.Xr ioctl 2 or
.Xr ifconfig 8 utility.
.Pp
The basic intent is to provide connectivity between two virtual
network stack instances.

View file

@ -58,6 +58,7 @@
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <net/bpf.h>
@ -96,6 +97,15 @@ static unsigned int next_index = 0;
#define EPAIR_LOCK() mtx_lock(&epair_n_index_mtx)
#define EPAIR_UNLOCK() mtx_unlock(&epair_n_index_mtx)
SYSCTL_DECL(_net_link);
static SYSCTL_NODE(_net_link, OID_AUTO, epair, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"Pair of virtual cross-over connected Ethernet-like interfaces");
static bool use_ether_gen_addr = false;
SYSCTL_BOOL(_net_link_epair, OID_AUTO, ether_gen_addr, CTLFLAG_RWTUN,
&use_ether_gen_addr, false,
"Generate MAC with FreeBSD OUI using ether_gen_addr(9)");
struct epair_softc;
struct epair_queue {
struct mtx mtx;
@ -494,6 +504,17 @@ epair_clone_match(struct if_clone *ifc, const char *name)
return (1);
}
static void
epair_generate_mac_byname(struct epair_softc *sc, uint8_t eaddr[])
{
struct ether_addr gen_eaddr;
int i;
ether_gen_addr_byname(if_name(sc->ifp), &gen_eaddr);
for (i = 0; i < ETHER_ADDR_LEN; i++)
eaddr[i] = gen_eaddr.octet[i];
}
static void
epair_clone_add(struct if_clone *ifc, struct epair_softc *scb)
{
@ -501,9 +522,12 @@ epair_clone_add(struct if_clone *ifc, struct epair_softc *scb)
uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
ifp = scb->ifp;
/* Copy epairNa etheraddr and change the last byte. */
memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN);
eaddr[5] = 0x0b;
if (!use_ether_gen_addr) {
/* Copy epairNa etheraddr and change the last byte. */
memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN);
eaddr[5] = 0x0b;
} else
epair_generate_mac_byname(scb, eaddr);
ether_ifattach(ifp, eaddr);
if_clone_addif(ifc, ifp);
@ -718,7 +742,10 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len,
/* Finish initialization of interface <n>a. */
ifp = sca->ifp;
epair_setup_ifp(sca, name, unit);
epair_generate_mac(sca, eaddr);
if (!use_ether_gen_addr)
epair_generate_mac(sca, eaddr);
else
epair_generate_mac_byname(sca, eaddr);
ether_ifattach(ifp, eaddr);