> On 22 Nov 2022, at 16:13, Andrew Hewus Fresh <and...@afresh1.com> wrote:
>
> On Mon, Nov 21, 2022 at 04:56:07PM +0100, Martijn van Duren wrote:
>> On Sun, 2022-11-20 at 19:35 -0700, Theo de Raadt wrote:
>>> Steve Litt <sl...@troubleshooters.com> wrote:
>>>
>>>> Vitaliy Makkoveev said on Mon, 21 Nov 2022 03:48:21 +0300
>>>>
>>>>>> On 20 Nov 2022, at 18:06, Odd Martin Baanrud <mar...@lb7ye.net>
>>>>>> wrote:
>>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> I have a Raspberry Pi 4 with 2 USB NIC’s attached.
>>>>>> One via USB3 (ure0), and the other via USB2 (ure1).
>>>>>> Since they are connected to different USB interfaces, I thaught they
>>>>>> would get configured the same way on reboot. But that’s not the case.
>>>>>> They became swapped on reboot.
>>>>>> Is there a way to “lock” the configuration I want?
>>>>>> So the USB3 NIC always become ure0, and the USB2 ure1.
>>>>>>
>>>>>> Regards, Martin
>>>>>>
>>>>>
>>>>> You could parse ifconfig(8) output to determine which names network
>>>>> interfaces received. But unfortunately, you can’t rename interfaces.
>>>>
>>>> During your parsing you could assign each one to an environment
>>>> variable such that, for instance, $lan contains the network card name
>>>> of the LAN one, and $wan contains the network name of the one going to
>>>> the Internet. Unfortunately, this would probably mean changing a lot of
>>>> existing shellscripts, but it's doable.
>>>
>>> But that is not the problem.
>>>
>>> hostname.* installs addresses on an interface, based upon the name of that
>>> interface.
>>>
>>> So it is too late for what you suggest.
>>>
>>> Unless the suggestion is have each hostname.* do a !command to a script
>>> which
>>> does the assigning. That is pretty crazy.
>>>
>>> pf.conf is not the problem either, because that can be entirely written
>>> using
>>> egress and groups.
>>>
>>>
>>>
>>> There is a problem with device attachment -> naming a device at that
>>> moment -> using that name in netstart.. but I am not sure how we could
>>> solve this without creating bigger problems for everyone else in the
>>> other non-hot-plug configurations, which is the majority of users with
>>>> 1 network device.
>>>
>>> We also hit this problem with disks, and we worked around it with the
>>> DUID subsystem.
>>>
>>>
>>> I suppose there is some argument that we should support hostname.MAC
>>> files
>>>
>> I don't have a usecase for this myself, but it seemed like a nice
>> exercise and might get the ball rolling. I also don't have much
>> experience with our rc/netstart shellcode, so I'm expecting this diff
>> should be taken as a starting-point iff we want something like this.
>>
>> I've chosen to error out on missing lladdr, duplicate lladdr and when
>> there's a hostname.if for both the lladdr and the if variant. This means
>> that there's smaller chance for order confusion or doubly applied
>> configs. Downside is that if someone decided to backup their hostname.if
>> to hostname.lladdr that will break their setup. However, I don't expect
>> people to backup their config files in this manner, but you never know.
>>
>> Errors:
>> On duplicate lladdr (in this case em0 and iwx0 in trunk0):
>> $ doas sh /usr/src/etc/netstart 88:a4:c2:fb:84:77
>> netstart: /etc/hostname.88:a4:c2:fb:84:77: unique if for lladdr not found.
>>
>> On missing lladdr:
>> $ doas sh /usr/src/etc/netstart 88:a4:c2:fb:84:76
>> netstart: /etc/hostname.88:a4:c2:fb:84:76: unique if for lladdr not found.
>>
>> And having both hostname.if and hostname.lladdr installed:
>> $ doas sh ./netstart 00:11:22:33:44:55
>> netstart: /etc/hostname.00:11:22:33:44:55: duplicate config found in
>> /etc/hostname.vio0.
>> $ doas sh ./netstart vio0
>> netstart: /etc/hostname.vio0: duplicate config found in
>> /etc/hostname.00:11:22:33:44:55.
>>
>> Two omissions I considered but didn't implement:
>> 1) I didn't test if the lladdr is owned by one of `ifconfig -C`
>> interfaces. Not sure if this is an upside or downside.
>> 2) Allowing /etc/netstart if1 and parsing the hostname.lladdr1 and vice
>> versa.
>
>
> I got interested in this, and looked at it a bit. My diff is also a bit
> preliminary, but a couple of things.
>
> First, I only parse ifconfig output once and save the LLADDR_MAP to look
> up later. This makes the lookup functions a bit simpler. Also, the
> glob now uses xdigit, which seems more correct, unless there's something
> I am missing about mac addresses.
>
> I also thought the error message for `netstart $lladdr` when
> /etc/hostname.$lladdr doesn't exist, but /etc/hostname.$if does was poor
> (it claimed duplicate configs which wasn't true) so I thought the
> easiest solution was to implement your #2 there and allow it to start
> the $if when you specify the $lladdr.
>
> Unfortunately, I then looked at the clock and realized it's time for
> bed, but I figured you might be interested in another take, even if it's
> probably incomplete. In any case, tomorrow is dinner with friends, so
> it will be Wednesday before I again have a chance to think on this.
There are a few things to keep in mind if we're going to use lladdrs like this.
vlan interfaces start with their lladdr as 00:00:00:00:00:00 and then assume
the lladdr of the parent interface when that is configured.
Clonable devices (eg, egre, vport, aggr, etc) tend to generate random lladdrs
when they're created. If you want a consistent lladdr for these you configure
that in /etc/hostname.vportX or whatever you're using.
"Platform deficient" systems like arm SBCs don't always do a good job of
providing lladdrs for their ethernet interfaces. I'm working on one now that
has rge(4) and it comes up with an lladdr of 00:00:00:00:00:00. I have another
one where the drivers fall back to randomly generating an lladdr if none is set
by u-boot/edk/etc.
I don't think any of these are showstoppers, but do need to be considered.
> Index: etc/netstart
> ===================================================================
> RCS file: /cvs/src/etc/netstart,v
> retrieving revision 1.229
> diff -u -p -r1.229 netstart
> --- etc/netstart 5 Nov 2022 12:06:05 -0000 1.229
> +++ etc/netstart 22 Nov 2022 05:55:40 -0000
> @@ -92,6 +92,49 @@ parse_hn_line() {
> set +o noglob
> }
>
> +LLGLOB='[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]'
> +LLGLOB="$LLGLOB:$LLGLOB:$LLGLOB"
> +
> +set -A LLADDR_MAP -- $(
> + ifconfig | while IFS= read -- _line; do
> + if [[ "$_line" = +([[:alpha:]])+([[:digit:]]):* ]]; then
> + _if=${_line%:*}
> + elif [[ -n "$_if"
> + && "$_line" = +([[:space:]])lladdr\ $LLGLOB ]]; then
> + print "$_if,${_line#*lladdr }"
> + _if=
> + fi
> + done
> +)
> +
> +# Find if for lladdr
> +# Usage: lladdr2if xx:xx:xx:xx:xx:xx
> +# Duplicate lladdrs result in error.
> +lladdr2if() {
> + local _lladdr=$1 _if=""
> + for m in "${LLADDR_MAP[@]}"; do
> + if [[ "$_lladdr" = "${m#*,}" ]]; then
> + [[ -n "$_if" ]] && return 1
> + _if="${m%,*}"
> + fi
> + done
> + print -- "$_if"
> + return 0
> +}
> +
> +# Find lladdr for if
> +# Usage: if2lladdr if1
> +if2lladdr() {
> + local _if=$1
> + for m in "${LLADDR_MAP[@]}"; do
> + if [[ "$_if" = "${m%,*}" ]]; then
> + print -- "${m#*,}"
> + break
> + fi
> + done
> + return 0
> +}
> +
> # Create interface $1 if it does not yet exist.
> # Usage: ifcreate if1
> ifcreate() {
> @@ -132,15 +175,37 @@ vifscreate() {
> # Start a single interface.
> # Usage: ifstart if1
> ifstart() {
> - local _if=$1 _hn=/etc/hostname.$1 _cmds _i=0 _line _stat
> + local _if=$1 _hn _cmds _i=0 _line _stat _lladdr
> set -A _cmds
>
> + if [[ "$_if" = $LLGLOB ]]; then
> + _lladdr=$_if
> + if ! _if="$(lladdr2if "$_if")"; then
> + print -u2 "${0##*/}: unique if for lladdr $_lladdr not
> found."
> + return
> + fi
> + else
> + _lladdr="$(if2lladdr "$_if")"
> + fi
> +
> # Interface names must be alphanumeric only. We check to avoid
> # configuring backup or temp files, and to catch the "*" case.
> [[ $_if != +([[:alpha:]])+([[:digit:]]) ]] && return
>
> - if [[ ! -f $_hn ]]; then
> - print -u2 "${0##*/}: $_hn: No such file or directory."
> + if [[ -n "$_if" && -e "/etc/hostname.$_if" ]]; then
> + _hn="/etc/hostname.$_if"
> + fi
> +
> + if [[ -n "$_lladdr" && -e "/etc/hostname.$_lladdr" ]]; then
> + if [[ -n "$_hn" ]]; then
> + print -u2 "${0##*/}: duplicate configs found in $_hn
> and /etc/hostname.$_lladdr."
> + return
> + fi
> + _hn="/etc/hostname.$_lladdr"
> + fi
> +
> + if [[ -z "$_hn" ]]; then
> + print -u2 "${0##*/}: /etc/hostname.$1: No such file or
> directory."
> return
> fi
>
> @@ -180,7 +245,7 @@ ifstart() {
> # Start "$1" interfaces in order or all interfaces if empty.
> # Don't start "$2" interfaces. "$2" is optional.
> ifmstart() {
> - local _sifs=$1 _xifs=$2 _hn _if _sif _xif
> + local _sifs=$1 _xifs=$2 _hn _if _sif _xif _lladdr
>
> for _sif in ${_sifs:-ALL}; do
> for _hn in /etc/hostname.+([[:alpha:]])+([[:digit:]]); do
> @@ -194,6 +259,13 @@ ifmstart() {
>
> # Start wanted ifs.
> [[ $_sif == @(ALL|${_if%%[0-9]*}) ]] && ifstart $_if
> + done
> + for _hn in /etc/hostname.$LLGLOB; do
> + [[ -f $_hn ]] || continue
> + _lladdr=${_hn#/etc/hostname.}
> +
> + # Start wanted ifs.
> + [[ $_sif == @(ALL|${_lladdr}) ]] && ifstart $_lladdr
> done
> done
> }