___            __             __                  __
          / _ \__ _____ _/ /______  ___ / /__    _____  ____/ /__
         / // / // / _ `/ /___/ _ \/ -_) __/ |/|/ / _ \/ __/  '_/
        /____/\_,_/\_,_/_/   /_//_/\__/\__/|__,__/\___/_/ /_/\_\
                  ___                __
                 / _ \___ ____ ___  / /  ___ __________ __
                / , _/ _ `(_-</ _ \/ _ \/ -_) __/ __/ // /
               /_/|_|\_,_/___/ .__/_.__/\__/_/ /_/  \_, /
                            /_/                    /___/


This document describes an old Raspberry configuration that I used to run
until summer 2022.

It is still interesting, as it describes how to configure a FreeBSD
machine machine with two very similar network interfaces, reliably
assigned to different purposes.  In my case one network interface was
exposed on the Open Internet, while the second was connected on the
internal LAN.


HOW THINGS USED TO BE

We used to have broadband on optical fiber. The ISP used to provide us
with *two* public dynamic IPv4 addresses, assigned via DHCP.

One address was taken by the home router: a custom APU6B4 running OpenWRT.
The other dynamic public IP was assigned to the Raspberry PI at hand, so
it was reachable from the Internet.  As part of the boot sequence, a
system service used to register the Raspberry to a dynamic DNS.

The Raspberry was also attached to the internal LAN through a USB network
interface. This was so for a few reasons:

- The Raspberry could expose services without enabling port forwarding on
  the home router.

- The Raspberry was directly accessible from the LAN: no need to exit on
  Internet and reach back in if, say, I was working from home.

- I could use the Raspberry to bridge operations on the router (e.g. system
  upgrade) without the risk of locking myself out if the router was
  misconfigured.


RASPBERRY NETWORK SETUP

Both ethernet interfaces are managed through the USB controller.  This can
be determined on FreeBSD by looking at the output of ifconfig(8), where
the two interfaces are listed as ue0 and ue1.  On FreeBSD the name of the
interface depends on the driver in use.  The same information can also be
verified by looking at the device tree via devinfo(8).

On FreeBSD, all network interfaces are handled by default via DHCP.
Having dynamic addresses on both interfaces would work as far as
connectivity is concerned.  It would determine make the default gateway
assignment unpredictable.

This problem has been tackled by assigning a static IP on the interface
connected to the LAN, since the ISP will only assign public IP
dynamically.  The rc.conf(5) manpage explains how to disable the DHCP for
a specific interface.

It is difficult to tell the two interfaces apart by their names, since as
I mentioned above they use using the same driver, and I can't trust the
enumeration to be predictable.  I used devd(8) to rename the interfaces
based on their mac address.


USING DEVD TO CONSISTENTLY NAME INTERFACES

1. Install devd configuration (devd needs to be restarted)

	# more /usr/local/etc/devd/ifnet_rename.conf
	notify 100 {
		match "system"		"IFNET";
		match "type"		"ATTACH";
		match "subsystem"	"ue[0-9]+";
		action "/usr/local/sbin/ifrename $subsystem | xargs -I{} /etc/pccard_ether {} start";
	};

2. The rename script

	# more /usr/local/sbin/ifrename
	#!/bin/sh

	set -e

	self="${0##*/}"
	dev="${1:?device}"
	new_name=

	log() {
		logger -p local0.info "$self: $*"
	}

	mac="$(
		ifconfig="$(ifconfig "$dev")"
		printf %s "$ifconfig" | sed -n '/ether/s/.* //p'
	)"

	case "$mac" in
	'<FIRST MAC ADDRESS>')
		# main ethernet
		new_name=isp
		;;
	'<SECOND MAC ADDRESS>')
		# usb ethernet
		new_name=lan
		;;
	esac

	if [ -n "$new_name" ]; then
		log "rename $dev -> $new_name"
		ifconfig "$dev" name "$new_name"
	else
		log "keep name $dev"
	fi

3. The configurations:

	# grep ifconfig /etc/rc.conf
	ifconfig_isp="DHCP"
	ifconfig_lan="inet 192.168.1.254 netmask 255.255.255.0"


THINGS I LEARNED WHILE TESTING THE NET SETUP

To see devd in action, the interface must be re-dected...

This is the first attempt at it (failed):

   1. get device name with devinfo

   2. detach device (Danger: cuts the network, don't brick it!)

	# devctl detach muge0

   3. re-attach device: all failed

	# devctl reattach muge0 # devctl rescan muge0 # devctl ...

Second attempt (success):

Sine the device is under usb, force the whole USB bus to be rescanned.
Danger: this will cut the network Tip: always working under a screen(1)
or tmux(1) makes things much easier!

	# usbconfig reset


SEE ALSO

devctl(4) devd.conf(5) devd(8) devinfo(8)