Becoming friends with FreeBSD
You seem to be on a partially correct path. I presume you have a lot of knowledge on Unix but not so much an actual FreeBSD system. The reason I am guessing this is you have approached it in a slightly different way than the typical user of rc.d in FreeBSD.
I find the question a bit thin as I personally would rather chase why the arp goes missing. But we are given precious little information. Instead we jump to conclusions. They do however pose some interesting questions on how to do stuff on FreeBSD. Just bear in mind the huge caveat emptor that we might end up using a wrench as a hammer.
Writing rc scripts
The FreeBSD startup scripts live in /etc/rc.d
but you should never create anything there but leave that directory to the Operating System. Otherwise you risk having your things overwritten during an update. If you want to write your own startup/daemon/service scripts then the best location would be in /usr/local/etc/rc.d
Recommended file locations are documented in hier
And rather than writing everything from scratch you can get a lot of helper functions by reading Practical rc.d scripting in BSD
/etc/rc.conf.d/*
You ask in a comment if you can use it in a script in /etc/rc.conf.d/*
. Please please do not do this. Files from here are sourced at startup - but the purpose for this directory is to have small snippets with configuration settings (see rc.conf). Most people simply use the file /etc/rc.conf
to configure the system options - but you can split these into small segments and put them into /etc/rc.conf.d
even though it is not as common.
It would be better to put your more generic statup script in /etc/rc.local which is still supported. But I would still recommend creating a proper rc script and put it in /usr/local/etc/rc.d
If you want to ignore rc scripts altogether another common way to start a generic script at boot is to use the @reboot keyword in crontab
I would however say that you do not need to create a new rc script as the functionality is already there.
static_arp
Static arp is actually well documented - it is however very simple. The "missing" documentation might be how rc scripts are handled. It is documented in rc.conf:
static_arp_pairs
(str) Set to the list of static ARP pairs that are to be
added at system boot time. For each whitespace separated
element in the value, a static_arp_<element> variable is
assumed to exist whose contents will later be passed to a
``arp -S'' operation. For example
static_arp_pairs="gw"
static_arp_gw="192.168.1.1 00:01:02:03:04:05"
This means that you can add 3 static arp entries which will survive reboot by adding these lines to /etc/rc.conf (I recommend using the sysrc command):
static_arp_pairs="a b c"
static_arp_a="1.2.3.4 11:22:33:44:55:66"
static_arp_b="1.2.3.5 22:33:44:55:66:77"
static_arp_c="1.2.3.6 33:44:55:66:77:88"
Or in your specific case:
static_arp_pairs="myarp"
static_arp_myarp="172.16.16.9 11:54:33:A8:B2:6B"
The script handling this is part of the OS and is placed in /etc/rc.d/static_arp
and is very simple. It only supports "start" and "stop" commands.
You can call it from anywhere using:
/etc/rc.d/static_arp start
But I would prefer using the service command:
service static_arp start
If for some reason you feel tempted to edit/change /etc/rc.d/static_arp
then please do not! Root is omnipotent and you can do what you want - but you risk it will be replaced. What you should do is cp /etc/rc.d/static_arp /usr/local/etc/rc.d/mystatic_arp
and have the modified version live there. Notice the name change and make sure it is reflected within the script!
Recycling physical link
If you are used to other systems you might simply be taking the interface up/down using ifconfig. But on FreeBSD you should consider using:
service netif restart <interface>
I have honestly not tested if this brings the static_arp along as well. Or something along the lines of:
service netif stop <interface>
...
service netif start <interface>
service routing restart
service static_arp start
But cycling the physical link could be (un)plugging the cable? Again I am not sure what happens to the arp table then. I would expect it to still be in place as we have not put down the interface administratively.
UPDATE: @namezero has confirmed in a comment that arp entires set with static_arp do survive physical disconnects.
But we should examine this a little further to fully understand your case. This is then as close as I can get to answer "a. A good way to prevent this"
cron
If we get no notification of the physical link - then I do not see a better way than monitoring it. If we keep the script simple - then we can leave it to a regular cron.
devd to the rescue
If we are able to see the change from the OS then we have a nice path forward. The device state change daemon devd comes in handy. Your description is lacking so I will then assume that we either have a LINK_UP or a LINK_DOWN to act on.
Create the file /etc/devd/interface.conf with the content:
notify 0 {
match "system" "IFNET";
match "subsystem" "(em0|em1)";
match "type" "LINK_DOWN";
action "/usr/local/sbin/alertme.sh $subsystem"
}
This will notify you for the network interfaces em0 and em1.
So it could be as simple as:
notify 0 {
match "system" "IFNET";
match "subsystem" "(em0|em1)";
match "type" "LINK_UP";
action "/etc/rc.d/static_arp start"
}
This does however feel a bit of a kludge to me as I would spend more time discovering why the arp entries are missing. But I hope these different pointers can get you in "some" direction.
Summary
This brings us to this shortlist which outlines how you can live a happier life with FreeBSD:
- System settings should live in /etc/rc.conf
- If you want your own rc scripts put them in /usr/local/etc/rc.d
- If you want a simple startup script put it in /etc/rc.local (you can source rc if you want)
- If you want a truly generic script at startup use @reboot with crontab
- Use sysrc when editing
/etc/rc.conf
- Use service when interacting with rc scripts
- Use devd acting on device state changes
static_arp_pairs
in/etc/rc.conf
is for.static_arp_pairs="foo"
andstatic_arp_foo="1.2.3.4 11:22:33:44:55:66"
/etc/rc.conf.d/*
also?static_arp_pairs
survive link cycles?