Page MenuHomeFreeBSD

epair: Simplify mac address generation
AbandonedPublic

Authored by kp on Apr 14 2020, 12:17 PM.

Details

Reviewers
bz
kevans
eugen_grosbein.net
Group Reviewers
network
Summary

Use ether_gen_addr() to generate the mac address for epair interfaces.
This means we use the FreeBSD OUI rather than a locally administered
address from now on.

We no longer use the full last byte to distinguis a and b, but only the
last nibble. This slightly increases the range of available addresses
and thus reduces the odds of a conflict.

Diff Detail

Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 30489
Build 28241: arc lint + arc unit

Event Timeline

kp created this revision.Apr 14 2020, 12:17 PM
kevans accepted this revision.Apr 14 2020, 12:29 PM

LGTM, thanks!

This revision is now accepted and ready to land.Apr 14 2020, 12:29 PM
eugen_grosbein.net requested changes to this revision.Apr 14 2020, 1:16 PM

Sadly, ether_gen_addr() cannot be used for epair safely. Your change removes parts of code that was brought in for a reason. This change would re-introduce problems fixed by code removed. Please read PRs 184149 and 229957 for details.

The problem is that ether_gen_addr() uses too little varying information to generate hash used for MAC randomization, so it would generate non-unique MAC addresses in case of epair.

This revision now requires changes to proceed.Apr 14 2020, 1:16 PM

Sadly, ether_gen_addr() cannot be used for epair safely. Your change removes parts of code that was brought in for a reason. This change would re-introduce problems fixed by code removed. Please read PRs 184149 and 229957 for details.

The problem is that ether_gen_addr() uses too little varying information to generate hash used for MAC randomization, so it would generate non-unique MAC addresses in case of epair.

This is dependent on a change @kp is making for if_bridge, where ether_gen_addr factors in jail name to generate unique addresses for vnet jails, which would seem to solve at least one if not both.

kp added a comment.Apr 14 2020, 1:35 PM

The problem is that ether_gen_addr() uses too little varying information to generate hash used for MAC randomization, so it would generate non-unique MAC addresses in case of epair.

This is the change kevans refers to: https://reviews.freebsd.org/D24383

It makes ether_gen_addr() include the (unique) jail name in the MAC address generation.

You still miss the point. Please read PR 229957 there all epairs are created within host, so they have same UUID. But after epair is created and MAC generated, epair get moved to another VNET, so next one may be created within host with same properties and get same MAC address.

kevans added a comment.EditedApr 14 2020, 4:37 PM

You still miss the point. Please read PR 229957 there all epairs are created within host, so they have same UUID. But after epair is created and MAC generated, epair get moved to another VNET, so next one may be created within host with same properties and get same MAC address.

The part that I find disconcerting about this is this part in the removed comment:

  • The result would be hopefully unique. Note that the "a" component of an epair instance may get moved to a different VNET after creation. In that case its index will be freed and the index can get reused by new epair instance.

I don't see where this behavior makes any sense, assuming the "b" end stays in the vnet that it originated in. Otherwise, you may end up with e.g. epair0a and epair0b[?] that aren't connected because the 'a' side to that epair0b got moved. IMO this should be using a per-VNET unr and not freeing the unit number unless/until both ends have evacuated the VNET. However, you may still run into problems if you decide to evacuate both ends (e.g. direct connection between two VNET jails?), hmm..

That said, I can't seem to reproduce this behavior at all in any form. I've created two jails on separate vnets and a new epair0; distributing one or both ends of the epair to new vnet(s) yields an inability to create a new epair0 on the host until the original's been destroyed.

kp added a comment.EditedApr 14 2020, 5:17 PM

You still miss the point. Please read PR 229957 there all epairs are created within host, so they have same UUID. But after epair is created and MAC generated, epair get moved to another VNET, so next one may be created within host with same properties and get same MAC address.

Unless I misunderstood you that doesn't appear to be the case:

(kp@freebsd_current_zfs)  ~ % sudo jail -c name=iron2 persist vnet                                                                                                        [17:14]
(kp@freebsd_current_zfs)  ~ % sudo jail -c name=iron persist vnet                                                                                                         [17:15]
(kp@freebsd_current_zfs)  ~ % sudo ifconfig epair create                                                                                                                  [17:15]
epair0a
(kp@freebsd_current_zfs)  ~ % sudo ifconfig epair                                                                                                                         [17:15]
(kp@freebsd_current_zfs)  ~ % ifconfig epair0a                                                                                                                            [17:15]
epair0a: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 58:9c:fc:10:5f:5a
        groups: epair
        media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
        status: active
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
(kp@freebsd_current_zfs)  ~ % sudo ifconfig epair0a vnet iron                                                                                                             [17:15]
(kp@freebsd_current_zfs)  ~ % sudo ifconfig epair0b vnet iron2                                                                                                            [17:15]
(kp@freebsd_current_zfs)  ~ % sudo ifconfig epair create                                                                                                                  [17:15]
epair1a
(kp@freebsd_current_zfs)  ~ % sudo ifconfig epair0 create                                                                                                                 [17:15]
ifconfig: SIOCIFCREATE2: File exists
(kp@freebsd_current_zfs)  ~ % ifconfig epair1a                                                                                                                            [17:15]
epair1a: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 58:9c:fc:00:1a:0a
        groups: epair
        media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
        status: active
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>

I can't create epair0 again even though it no longer exists in the host vnet.

I haven't been paying attention to this, but IME the problem with epair (and also bridge) interfaces was always that the generator would come up with the same MAC address on different *machines*. We simply gave up and manually assigned LAA MAC addresses to all such interfaces.

I haven't been paying attention to this, but IME the problem with epair (and also bridge) interfaces was always that the generator would come up with the same MAC address on different *machines*. We simply gave up and manually assigned LAA MAC addresses to all such interfaces.

As for epair, that your problem is different and should not happen if you use one of supported branches. Or maybe you were cloning machines and not paying attention for their /etc/hostid files to be different (and hence, their sysctls kern.hostid/kern.hostuuid).

In D24416#537135, @kp wrote:

I can't create epair0 again even though it no longer exists in the host vnet.

Now this is the case, but is it guaranteed/documented somehow or is it just another implementaion detail in the HEAD that could change with another commit?

kp abandoned this revision.Apr 15 2020, 9:16 AM