After staring at the output of $(strings /sbin/ifup | grep route), I was able to make two observation that in turn lead me to a fully new approach to the wrapper script. The outcome should be superior to the previous patch by the order of a magnitude. The new script is attached in its entirety with this message, so I will discuss the ideas behind this rewrite. The main idea is a simple intention: 1. Do not modify command line arguments. Pass almost everything to /lib/freebsd/route. The strings in "ifup" lead to two initial observations: 2. We need to support a single Debian native option: "-A inet6". This must go between "route" and the command "add". By the way, only commands "add" and "del" are generated from ifupdown, all other command calls can be passed verbatim. 3. When ifup/ifdown passes a non-elementary route, there is a GNU/Linux native keyword "gw" present. If either of these markers is missing, then the string from ifupdown could equally well pass for a FreeBSD-versioned command. So, what happens with the keyword "gw" present? 4. The keyword "gw" must not be passed to /lib/freebsd/route. One issue creeps up: What if a host or a network is named "gw"? The present script disregards this possibility. A TODO for later! A command call from ifup/ifdown containing "gw" can thus be used as a state in a finite machine. It entails two further principles: 5. In gw-state, any use of "metric $num" must be discarded. No immediate counterpart present in FreeBSD. 6. Ifup/ifdown appends an interface name at the end, which affects gw-state. Since the meaning of "dev $name" in GNU/Linux and "-interface $name" do not carry identical connotations, the appended name must be dropped. That is it. My wrapper proposal implements these six observations. It works like a charm on my machine. Although a single homed system, it is fun to use "route get" for viewing routes, teasing with options and the like. I suggest dropping all tests of the initial patch, instead commencing the evaluation of the wrapper proposal. Best regards, Mats E A
#!/bin/sh # # /sbin/route # # Wrapper script around /lib/freebsd/route # crafted to catch the routing commands issued # by /sbin/ifup and /sbin/ifdown, translating # them into valid FreeBSD commands, at the same # time preserving all BSD native routing input. # # Authors: Axel Beckert, Mats Erik Andersson set -e if [ $# = 0 ] ; then # Issue usage info /lib/freebsd/route fi args="" # Capture all options first. Save them for later. # One Debian endemic addition: -A family. # Typically: -A inet6 # opts="" af="" while [ $# -gt 0 ]; do case "$1" in -*) # One Debian addition. if [ "$1" = "-A" ] ; then shift if [ -n "$1" ] ; then af="-$1" shift continue fi # Incorrect usage, call for help /lib/freebsd/route fi # A native option remains opts="${opts} $1" shift ;; *) # Must be the beginning of a command mode line. break ;; esac done cmd="$1" shift # Command originating from ifudown can only be # either for "add" or for "del". # # The commands from "ifupdown" are acceptable # as long as they do not contain the keyword "gw". # In case the command does so, then the very last # command line argument is the name of the interface. # We ignore it for now, since an interface specification # do not carry the same connotation in FreeBSD as it # does in GNU/Linux. # # The keyword "metric" seems unknown for FreeBSD, # so it is filtered off. if [ "$cmd" = "add" -o "$cmd" = "del" ] ; then # Our simple state machine HAVE_SEEN_GW="" while [ $# -gt 0 ]; do if [ -n "$HAVE_SEEN_GW" ] ; then if [ $# -eq 1 ] ; then # We have reach the end. An interface name # appears as last argument, since we are in # a state caused by a call from ifupdown. # We simply discard the interface name. break fi if [ "$1" = "metric" ] ; then # Ignored, together with its argument shift else args="${args} $1" fi else if [ "$1" = "gw" ] ; then # Change state and discard "gw", # hoping that no administrator ever # names a host or a network as "gw". HAVE_SEEN_GW="YES" else # This ingredient is important. Add it. args="${args} $1" fi fi shift done else # Must have a native command, whatever the content. args="$@" fi exec /lib/freebsd/route ${opts} ${cmd} ${af} ${args}
Attachment:
signature.asc
Description: Digital signature