The branch main has been updated by ronald: URL: https://cgit.FreeBSD.org/src/commit/?id=590493c1419092e98f7ad1dcadb886973502341e
commit 590493c1419092e98f7ad1dcadb886973502341e Author: Ronald Klop <ron...@freebsd.org> AuthorDate: 2025-07-03 16:33:03 +0000 Commit: Ronald Klop <ron...@freebsd.org> CommitDate: 2025-08-05 14:53:04 +0000 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 MFC after: 2 weeks Relnotes: yes Differential Revision: https://reviews.freebsd.org/D51157 --- sys/net/if_epair.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index 7051e31565d4..4d35584925a1 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -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> @@ -97,6 +98,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; @@ -495,6 +505,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) { @@ -502,9 +523,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); @@ -719,7 +743,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);