On Tue, 2022-11-22 at 11:25 +0100, Claudio Jeker wrote:
> On Tue, Nov 22, 2022 at 09:25:08AM +0000, Stuart Henderson wrote:
> > Need to query (and set $if, which might be used in route commands etc) I 
> > think.
> > 
> 
> I would prefer if people took a step back from configuring interfaces by
> MAC address. It feels like a overly specific hack is introduced for
> a case that should be handled in a different way.
> 
> Not all interfaces have MAC addresses. E.g. umb(4) would need a
> different identifier (most probably the IMEI). Some interfaces inherit
> the MAC address from an other interface (vlan, trunk).
> 
> This requires the use of interface groups to 'rename' these interfaces
> e.g. as 'green' and 'blue' or 'in' and 'out'. So that you can use these
> handles in pf.conf and other commands (rad comes to mind). Not all
> commands work with interface groups. route(8) is such an example but there
> are more commands needing this.
> 
> Btw. a lot of this can be done already now by using '!' in hostname.if
> It wont be pretty but it is also not a common use case.

Maybe you're right, but as theo said doing it via !-commands is just
horrendous. Best I can think of is letting people write their own script
and call it via `!/path/to/script $if`, which is guaranteed going to end
messy.

Here's a completely other idea that might be more generic and hopefully
doesn't cause this same level of confusion. What if instead of adding
a new extension we let people do that themselves and add support for
including other files? Diff below does this and must still be considered
a PoC. And yes I know sed, which isn't allowed. But the command above it
does the same thing, so I'm not going to apologise for it in a PoC.

One downside in the current parse_hn_line format is that spaces other
than a single SP are completely butchered, but I'm not expecting much
problems there.

In addition to $if which is available for '!'-commands I also added
support for $lladdr.

$ cat /etc/hostname.em0 
. /etc/hostname.$lladdr
$ cat /etc/hostname.88\:a4\:c2\:fb\:84\:77 
autoconf
up
$ doas sh ./netstart -n em0                
{ ifconfig em0 || ifconfig em0 create; }
ifconfig em0 autoconf
ifconfig em0 up

martijn@

Index: netstart
===================================================================
RCS file: /cvs/src/etc/netstart,v
retrieving revision 1.229
diff -u -p -r1.229 netstart
--- netstart    5 Nov 2022 12:06:05 -0000       1.229
+++ netstart    23 Nov 2022 07:22:07 -0000
@@ -35,10 +35,38 @@ stripcom() {
        done <$_file
 }
 
+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 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
+}
+
 # Parse and "unpack" a hostname.if(5) line given as positional parameters.
 # Fill the _cmds array with the resulting interface configuration commands.
 parse_hn_line() {
-       local _af=0 _name=1 _mask=2 _bc=3 _prefix=2 _c _cmd _prev _daddr _dhcp 
_i
+       local _af=0 _name=1 _mask=2 _bc=3 _prefix=2 _c _cmd _prev _daddr _dhcp
+       local _i _file _line
        set -A _c -- "$@"
        set -o noglob
 
@@ -84,6 +112,17 @@ parse_hn_line() {
                ;;
        '!'*)   _cmd=$(print -- "${_c[@]}" | sed 's/\$if/'$_if'/g')
                _cmds[${#_cmds[*]}]="${_cmd#!}"
+               ;;
+       '.')    unset _c[_af]
+               _file="$(print -- "${_c[@]}" | sed -e 's/\$if/'$_if'/g' \
+                   -e 's/\$lladdr/'$(if2lladdr $_if)'/g')"
+               if [[ ! -f $_file ]]; then
+                       print -u2 "${0##*/}: $_file: No such file or directory."
+                       return
+               fi
+               while IFS= read -- _line; do
+                       parse_hn_line $_line
+               done<"$_file"
                ;;
        *)      _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}"
                ;;

Reply via email to