summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStig Thormodsrud <stig@vyatta.com>2010-10-26 14:48:22 -0700
committerStig Thormodsrud <stig@vyatta.com>2010-10-26 14:48:22 -0700
commit40461ef6ea9325b0dd1262cd3b99ffcbcf69dfd6 (patch)
treef1ef54222a2296bbed7103a2db1e44529e95d3a9
parent7dc4ac0cb122bc98f903f93fc83e93007de7c751 (diff)
parent3e0d01a69b7f70977375ab73a51cfc5004813065 (diff)
downloadvyatta-cfg-system-40461ef6ea9325b0dd1262cd3b99ffcbcf69dfd6.tar.gz
vyatta-cfg-system-40461ef6ea9325b0dd1262cd3b99ffcbcf69dfd6.zip
Merge branch 'mendocino' of http://git.vyatta.com/vyatta-cfg-system into mendocino
-rw-r--r--Makefile.am5
-rw-r--r--debian/changelog16
-rwxr-xr-xscripts/add_bootfile_eth_hwid29
-rwxr-xr-xscripts/mod_bootfile_eth_hwid36
-rwxr-xr-xscripts/rl-system.init20
-rwxr-xr-xscripts/system/vyatta_interface_rescan140
-rwxr-xr-xscripts/vyatta-bonding.pl45
-rwxr-xr-xscripts/vyatta_net_name512
-rw-r--r--sysconf/65-vyatta-net.rules13
-rw-r--r--sysconf/69-vyatta-net.rules25
-rw-r--r--templates/interfaces/bonding/node.def11
-rw-r--r--templates/interfaces/bonding/node.tag/arp-monitor/interval/node.def5
-rw-r--r--templates/interfaces/bonding/node.tag/arp-monitor/node.def1
-rw-r--r--templates/interfaces/bonding/node.tag/arp-monitor/target/node.def7
-rw-r--r--templates/interfaces/bonding/node.tag/hash-policy/node.def3
15 files changed, 420 insertions, 448 deletions
diff --git a/Makefile.am b/Makefile.am
index b4cfbe92..cfb0f96b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,6 +24,7 @@ sbin_SCRIPTS += scripts/vyatta-grub-setup
sbin_SCRIPTS += scripts/standalone_root_pw_reset
sbin_SCRIPTS += scripts/vyatta-passwd-sync
sbin_SCRIPTS += scripts/system/vyatta_check_username.pl
+sbin_SCRIPTS += scripts/system/vyatta_interface_rescan
sbin_SCRIPTS += scripts/system/vyatta_update_login.pl
sbin_SCRIPTS += scripts/system/vyatta_update_logrotate.pl
sbin_SCRIPTS += scripts/system/vyatta_update_resolv.pl
@@ -36,8 +37,6 @@ sbin_SCRIPTS += scripts/snmp/snmpd.init
sbin_SCRIPTS += scripts/keepalived/vyatta-keepalived.pl
sbin_SCRIPTS += scripts/keepalived/vyatta-vrrp-state.pl
sbin_SCRIPTS += scripts/telnetd.init
-sbin_SCRIPTS += scripts/add_bootfile_eth_hwid
-sbin_SCRIPTS += scripts/mod_bootfile_eth_hwid
sbin_SCRIPTS += scripts/dns-forwarding/vyatta-dns-forwarding.pl
sbin_SCRIPTS += scripts/dynamic-dns/vyatta-dynamic-dns.pl
sbin_SCRIPTS += scripts/vyatta-system-nameservers
@@ -86,7 +85,7 @@ sysconf_DATA += sysconf/capability.conf
libudevdir = /lib/udev
udevrulesdir = /lib/udev/rules.d
libudev_SCRIPTS = scripts/vyatta_net_name
-udevrules_DATA = sysconf/69-vyatta-net.rules
+udevrules_DATA = sysconf/65-vyatta-net.rules
rsyslogdir = /etc/rsyslog.d
rsyslog_DATA = sysconf/vyatta-log.conf
diff --git a/debian/changelog b/debian/changelog
index 3371d014..93bf4a2d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,19 @@
+vyatta-cfg-system (0.17.126) unstable; urgency=low
+
+ * Change vyatta_net_name into a perl script
+ * Sort the interface names when adding
+
+ -- Stephen Hemminger <stephen.hemminger@vyatta.com> Tue, 26 Oct 2010 14:35:45 -0700
+
+vyatta-cfg-system (0.17.125) unstable; urgency=low
+
+ * Fix bond hash policy
+ * Fix typo in hash_policy
+ * Wait to bring up bond interface until end
+ * Add bonding ARP monitor parmeters
+
+ -- Stephen Hemminger <stephen.hemminger@vyatta.com> Mon, 25 Oct 2010 10:20:08 -0700
+
vyatta-cfg-system (0.17.124) unstable; urgency=low
* Fix commit-uri bug.
diff --git a/scripts/add_bootfile_eth_hwid b/scripts/add_bootfile_eth_hwid
deleted file mode 100755
index 61deea56..00000000
--- a/scripts/add_bootfile_eth_hwid
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# add ethnet interface sub-block to configure file
-
-shopt -s extglob
-
-if [[ "$*" == *--help* ]] ; then
- echo ${0##*/} [test_]FILE INTERFACE HWID
- exit 0
-fi
-
-if [[ "$1" == test_* ]] ; then
- origfile=$1
- bootfile=/tmp/${1##*/}_$$
- cp $origfile $bootfile
- trap "diff -c $origfile $bootfile; rm -f $bootfile; exit 0" $?
-else
- origfile=
- bootfile=$1
-fi
-eth=$2
-hwid=$3
-
-sed -i '/^interfaces {$/,/^}$/ {
- /^}$/i\
- ethernet '"$eth"' {\
- hw-id '"$hwid"'\
- }
- }' $bootfile
diff --git a/scripts/mod_bootfile_eth_hwid b/scripts/mod_bootfile_eth_hwid
deleted file mode 100755
index feab64f1..00000000
--- a/scripts/mod_bootfile_eth_hwid
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-# modify interface sub-block
-
-shopt -s extglob
-
-if [[ "$*" == *--help* ]] ; then
- echo ${0##*/} [test_]FILE INTERFACE HWID
- exit 0
-fi
-
-if [[ "$1" == test_* ]] ; then
- origfile=$1
- bootfile=/tmp/${1##*/}_$$
- cp $origfile $bootfile
- trap "diff -c $origfile $bootfile; rm -f $bootfile; exit 0" $?
-else
- origfile=
- bootfile=$1
-fi
-eth=$2
-hwid=$3
-
-sed -i '/^interfaces {$/,/^}$/ {
- /^ ethernet '"$eth"' {$/ {
- :join
- /\n }$/ {
- /hw-id:\? / s/\(hw-id\):\? [0-9a-fA-F:]\+/\1 '"$hwid"'/
- /hw-id:\? /! s/}$/ hw-id '"$hwid"'\n }/
- b
- }
- N
- b join
- }
-}' $bootfile
-
diff --git a/scripts/rl-system.init b/scripts/rl-system.init
index 3e07e11e..989c51e4 100755
--- a/scripts/rl-system.init
+++ b/scripts/rl-system.init
@@ -105,20 +105,10 @@ clear_or_override_config_files ()
done
}
-udev_rescan ()
-{
- rm -f /tmp/vyatta_net_name_*
- udevadm trigger --subsystem-match=net && udevadm settle --quiet
- for ff in /tmp/vyatta_net_name_* ; do
- f=${ff##*/}
- cmd_name_hwid=${f/vyatta_net_name_/}
- cmd=${cmd_name_hwid%%_*}
- name_hwid=${cmd_name_hwid#*_}
- name=${name_hwid%_*}
- hwid=${name_hwid#*_}
- syslog $cmd $name $hwid
- $vyatta_sbindir/${cmd}_bootfile_eth_hwid $BOOTFILE $name $hwid
- done
+update_interface_config () {
+ if [ -d /dev/.udev/vyatta ]; then
+ $vyatta_sbindir/vyatta_interface_rescan /dev/.udev/vyatta $BOOTFILE
+ fi
}
create_ssh_host_keys () {
@@ -190,7 +180,7 @@ start () {
mkdir -p /var/run/vyatta
mkdir -p /var/log/vyatta
- udev_rescan
+ update_interface_config
create_ssh_host_keys || \
log_failure_msg "can't initialize ssh host keys"
clear_or_override_config_files || \
diff --git a/scripts/system/vyatta_interface_rescan b/scripts/system/vyatta_interface_rescan
new file mode 100755
index 00000000..2803099b
--- /dev/null
+++ b/scripts/system/vyatta_interface_rescan
@@ -0,0 +1,140 @@
+#! /usr/bin/perl
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2010 Vyatta, Inc.
+# All Rights Reserved.
+
+# Thus updates the configuration to add new interfaces.
+# It is run on boot after udev and before vyatta configuration.
+
+use strict;
+use lib "/opt/vyatta/share/perl5/";
+use Sys::Syslog qw(:standard :macros);
+use XorpConfigParser;
+use File::Copy;
+
+my $TMPFILE = "/tmp/config.boot.$$";
+
+# These vendors are known to violate the local MAC address assignment convention
+my %whitelist = (
+ '02:07:01' => 'Interlan',
+ '02:60:60' => '3Com',
+ '02:60:8c' => '3Com',
+ '02:a0:c9' => 'Intel',
+ '02:aa:3c' => 'Olivetti',
+ '02:cf:1f' => 'CMC',
+ '02:e0:3b' => 'Prominet',
+ '02:e6:d3' => 'BTI',
+ '52:54:00' => 'Realtek',
+ '52:54:4c' => 'Novell 2000',
+ '52:54:ab' => 'Realtec',
+ 'e2:0c:0f' => 'Kingston Technologies',
+);
+
+# Ignore devices with local assigned or invalid mac address,
+# these devices don't have a persistent address
+sub persistent_address {
+ my $mac = shift;
+
+ # is local assignment bit (IEEE802) not set?
+ return 1 unless ($mac =~ /^.[2367abef]:/);
+
+ # is address bogus?
+ return if ($mac eq '00:00:00:00:00:00');
+
+ # unless it is in whitelist, it is non persistent
+ $mac =~ /^([0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f])/;
+ return $whitelist{$1};
+}
+
+# Map from eth0 to ethernet
+# TODO make smarter if more types
+sub interface_type {
+ my $ifname = shift;
+
+ return "ethernet" if ($ifname =~ /^eth/);
+ return "wireless" if ($ifname =~ /^wlan/);
+
+ die "unknown interface name %s\n", $ifname;
+}
+
+sub get_hwid {
+ my $name = shift;
+
+ open (my $f, '<', $name)
+ or die "Can't open $name : $!";
+
+ my $hwaddr = <$f>;
+ chomp $hwaddr;
+ close $f;
+
+ return $hwaddr;
+}
+
+# vyatta_net_name leaves files in /dev/.udev/vyatta
+# the filename is the interface and the contents are the hardware id
+sub interface_rescan {
+ my ($VYATTAUDEV, $BOOTFILE) = @_;
+
+ # parse existing config
+ my $xcp = new XorpConfigParser();
+ $xcp->parse($BOOTFILE);
+
+ # get list of changed interfaces
+ opendir( my $dir, $VYATTAUDEV )
+ or die "Can't open $VYATTAUDEV : $!";
+ my @interfaces = grep { ! /^\./ } readdir($dir);
+ close $dir;
+
+ foreach my $ifname (sort @interfaces) {
+ my $ifpath = interface_type($ifname) . " $ifname";
+ if ($xcp->get_node(['interfaces', $ifpath])) {
+ syslog(LOG_INFO, "%s: is already in config file", $ifname);
+ next;
+ }
+
+ my $hwaddr = get_hwid("$VYATTAUDEV/$ifname");
+ unless (persistent_address($hwaddr)) {
+ syslog(LOG_INFO, "%s: skipping address %s is not persistent",
+ $ifname, $hwaddr);
+ next;
+ }
+
+ # Add new entry to config
+ syslog(LOG_INFO, "add config for %s hw-id %s", $ifname, $hwaddr);
+ $xcp->create_node(['interfaces',$ifpath,"hw-id $hwaddr"]);
+ }
+
+ # Rewrite new config file
+ open (my $tmp, '>', $TMPFILE)
+ or die "Can't open $TMPFILE : $!";
+
+ select $tmp;
+ $xcp->output(0);
+ select STDOUT;
+ close $tmp;
+
+ copy($TMPFILE, $BOOTFILE)
+ or die "Can't copy $TMPFILE to $BOOTFILE : $!";
+
+ unlink($TMPFILE);
+}
+
+# main
+die "vyatta_interface_rescan called with wrong args"
+ unless ($#ARGV == 1);
+
+openlog("vyatta-interface-rescan", "", LOG_DAEMON);
+
+interface_rescan(@ARGV);
+exit 0;
+
diff --git a/scripts/vyatta-bonding.pl b/scripts/vyatta-bonding.pl
index 3ecffdda..ced916d6 100755
--- a/scripts/vyatta-bonding.pl
+++ b/scripts/vyatta-bonding.pl
@@ -58,6 +58,16 @@ sub set_mode {
or die "Error: $intf can not set mode $val:$!\n";
}
+sub set_hash_policy {
+ my ( $intf, $hash ) = @_;
+
+ open my $fm, '>', "/sys/class/net/$intf/bonding/xmit_hash_policy"
+ or die "Error: $intf is not a bonding device:$!\n";
+ print {$fm} $hash, "\n";
+ close $fm
+ or die "Error: $intf can not set hash $hash:$!\n";
+}
+
sub get_slaves {
my $intf = shift;
@@ -131,26 +141,44 @@ sub if_up {
and die "Could not set $intf up ($!)\n";
}
+# Can't change mode when bond device is up and slaves are attached
sub change_mode {
my ( $intf, $mode ) = @_;
my $interface = new Vyatta::Interface($intf);
die "$intf is not a valid interface" unless $interface;
- my $primary = primary_slave( $intf, $interface->hw_address() );
+ my $bond_up = $interface->up();
+
+ if_down($intf) if ($bond_up);
+
+ # Remove all interfaces; do primary last
+ my $primary = primary_slave( $intf, $interface->hw_address());
my @slaves = get_slaves($intf);
+
foreach my $slave (@slaves) {
- remove_slave( $intf, $slave ) unless ( $primary && $slave eq $primary );
+ remove_slave( $intf, $slave ) unless ( $primary && $slave eq $primary );
}
remove_slave( $intf, $primary ) if ($primary);
- my $bond_up = $interface->up();
- if_down($intf) if $bond_up;
set_mode( $intf, $mode );
- if_up($intf) if $bond_up;
+ add_slave( $intf, $primary) if ($primary);
foreach my $slave ( @slaves ) {
- add_slave( $intf, $slave );
+ add_slave( $intf, $slave ) unless ($primary && $slave eq $primary);
}
+ if_up($intf) if ($bond_up);
+}
+
+# Can't change hash when bond device is up
+sub change_hash {
+ my ( $intf, $hash ) = @_;
+ my $interface = new Vyatta::Interface($intf);
+ die "$intf is not a valid interface" unless $interface;
+ my $bond_up = $interface->up();
+
+ if_down($intf) if $bond_up;
+ set_hash_policy( $intf, $hash );
+ if_up($intf) if $bond_up;
}
# bonding requires interface to be down before enslaving
@@ -179,6 +207,7 @@ sub remove_port {
sub usage {
print "Usage: $0 --dev=bondX --mode={mode}\n";
+ print " $0 --dev=bondX --hash=layerX\n";
print " $0 --dev=bondX --add=ethX\n";
print " $0 --dev=bondX --remove=ethX\n";
print print "modes := ", join( ',', sort( keys %modes ) ), "\n";
@@ -186,11 +215,12 @@ sub usage {
exit 1;
}
-my ( $dev, $mode, $add_port, $rem_port );
+my ( $dev, $mode, $hash, $add_port, $rem_port );
GetOptions(
'dev=s' => \$dev,
'mode=s' => \$mode,
+ 'hash=s' => \$hash,
'add=s' => \$add_port,
'remove=s' => \$rem_port,
) or usage();
@@ -198,5 +228,6 @@ GetOptions(
die "$0: device not specified\n" unless $dev;
change_mode( $dev, $mode ) if $mode;
+change_hash( $dev, $hash ) if $hash;
add_port( $dev, $add_port ) if $add_port;
remove_port( $dev, $rem_port ) if $rem_port;
diff --git a/scripts/vyatta_net_name b/scripts/vyatta_net_name
index de1fbcbf..c7b217d9 100755
--- a/scripts/vyatta_net_name
+++ b/scripts/vyatta_net_name
@@ -1,5 +1,5 @@
-#!/bin/bash
-# **** License ****
+#! /usr/bin/perl
+
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
@@ -10,349 +10,203 @@
# General Public License for more details.
#
# This code was originally developed by Vyatta, Inc.
-# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2010 Vyatta, Inc.
# All Rights Reserved.
-#
-# Authors: Tom Grennan <tgrennan@vyatta.com>
-# Bob Gilligan <gilligan@vyatta.com>
-# Description: search Vyatta config for interface name given address
-#
-# **** End License ****
-
-progname=${0##*/}
-debug=
-match=
-attr_address=0:0:0:0:0:0
-declare -i ethn=0
-udev_persistent_net_rules_file="/etc/udev/rules.d/70-persistent-net.rules"
-
-# Set log_file to "/dev/null" to turn off debugging
-log_file="/tmp/vnn_log"
-
-test -r /etc/default/vyatta && source /etc/default/vyatta
-
-# process command line variable overrides
-
-for arg ; do
- case "$arg" in
- --debug )
- debug=echo
- ;;
- --*=* )
- arg=${arg#--}
- eval ${arg%=*}=\"${arg#*=}\"
- ;;
- *=* )
- eval ${arg%=*}=\"${arg#*=}\"
- ;;
- *:*:*:*:*:* )
- attr_address=$arg
- ;;
- * )
- orig_kname=$arg
- ;;
- esac
-done
-
-: ${vyatta_prefix:=/opt/vyatta}
-: ${vyatta_sbindir:=${vyatta_prefix}/sbin}
-: ${vyatta_sysconfdir:=${vyatta_prefix}/etc}
-: ${BOOTFILE:=${vyatta_sysconfdir:-/opt/vyatta/etc}/config/config.boot}
-: ${DEFAULT_BOOTFILE:=${vyatta_sysconfdir:-/opt/vyatta/etc}/config.boot.default}
-
-shopt -s extglob nullglob
-
-# load cfg_eth_hwid array from the Vyatta config file by looking
-# for entries formatted as follows:
-#
-# interface {
-# ...
-# ethernet eth# {
-# ...
-# hw-id XX:XX:XX:XX:XX:XX
-# ...
-# }
-# }
-#
-# The result is an array named "cfg_net_hwid". Each element of the
-# array is formatted like this:
-#
-# eth#=xx:xx:xx:xx:xx:xx
-#
-declare -a cfg_net_hwid=( $( sed -ne '
- /^interfaces {/,/^}/ {
- /^ *ethernet eth[0-9]* {/,/^ $/ {
- /^ *ethernet/ {
- s/\r//
- s/.* eth\([0-9]\+\) {$/ eth\1=/
-# hold interface name
- h
- }
- /^.*hw-id:\?/ {
-# translate field name
- s/\r//
- s/.*hw-id:\? *//
-# tolower hex mac address
- y/ABCDEF/abcdef/
-# exchange hold and pattern space
- x
-# concatenate hold and pattern
- G
- s/\n//p
+use strict;
+use lib "/opt/vyatta/share/perl5/";
+use XorpConfigParser;
+use Vyatta::Config;
+use Sys::Syslog qw(:standard :macros);
+use Fcntl qw(:flock);
+
+my $BOOTFILE = "/opt/vyatta/etc/config/config.boot";
+my $UDEVDIR = "/dev/.udev";
+
+my $VYATTAUDEV = $UDEVDIR . "/vyatta";
+my $LOCKFILE = $UDEVDIR . "/.vyatta-lock";
+my $VYATTACFG = "/opt/vyatta/config/active";
+
+# Check if interface name is free to use
+sub is_available {
+ my ($interfaces, $ifname) = @_;
+
+ my $count = grep { $_ eq $ifname } values %$interfaces;
+ return ($count == 0);
+}
+
+# Find next available interface name
+sub find_available {
+ my ($interfaces, $ifprefix) = @_;
+ $ifprefix =~ s/\d+$//;
+
+ for (my $id = 0; ; $id++) {
+ my $ifname = sprintf("%s%d", $ifprefix, $id);
+
+ # is it in Vyatta config?
+ return $ifname if (is_available($interfaces, $ifname));
+ }
+}
+
+# Find the hardware id in the parsed config node for interface
+sub get_hwid_from_children {
+ my $children = shift;
+
+ foreach my $attr (@$children) {
+ next unless ($attr->{'name'} =~ /^hw-id ([0-9a-f:]+)/);
+ return $1;
+ }
+
+ return; # not found
+}
+
+
+# Leave file for vyatta_interface_rescan
+sub leave_rescan_hint {
+ my ($ifname, $hwaddr) = @_;
+ my $name = "$VYATTAUDEV/$ifname";
+
+ mkdir($VYATTAUDEV);
+ open (my $f, '>', $name)
+ or die "Can't create $name : $!";
+
+ print {$f} "$hwaddr\n";
+ close $f;
+ return 1;
+}
+
+# Determine network name to use based on Vyatta config during boot
+sub coldplug {
+ my ($ifname, $hwaddr) = @_;
+ my $xcp = new XorpConfigParser();
+ $xcp->parse($BOOTFILE);
+
+ my $interfaces = { };
+ my $inode = $xcp->get_node(['interfaces']);
+ if ($inode) {
+ foreach my $child (@{$inode->{'children'}}) {
+ next unless ($child->{'name'} =~ /^ethernet (.*)|^wireless (.*)/);
+
+ my $intf = $1;
+ my $hwid = get_hwid_from_children($child->{'children'});
+ next unless $hwid;
+
+ # TBD this could be a hash with name and path?
+ $interfaces->{$hwid} = $intf;
+ }
+ }
+
+ # is name already in config file
+ my $newname = $interfaces->{$hwaddr};
+ return $newname if ($newname);
+
+ # add already assigned names
+ if (opendir(my $dir, $VYATTAUDEV)) {
+ foreach my $intf (grep { ! /^\./ } readdir($dir)) {
+ if (open (my $f, '<', "$VYATTAUDEV/$intf")) {
+ my $hwid = <$f>;
+ close $f;
+ chomp $hwid;
+
+ $interfaces->{$hwid} = $intf;
}
}
- }' $BOOTFILE ))
+ }
+
+ # Does biosdevname have a suggestion?
+ my $biosname = `/sbin/biosdevname -i $ifname`;
+ chomp $biosname;
+ if ($biosname ne '') {
+ $newname = $biosname;
+ } else {
+ $newname = $ifname;
+ }
+
+ $newname = find_available($interfaces, $newname)
+ unless (is_available($interfaces, $newname));
+
+ leave_rescan_hint($newname, $hwaddr);
+
+ return $newname;
+}
+
+# Determine name from active config
+sub hotplug {
+ my ($ifname, $hwaddr) = @_;
+
+ openlog("vyatta-net-name", "", LOG_DAEMON);
+
+ # Parse active config
+ my $cfg = new Vyatta::Config;
+ $cfg->setLevel('interfaces');
+
+ my $interfaces = {};
+ foreach my $type ($cfg->listOrigNodes()) {
+ next unless ($type eq 'ethernet') || ($type eq 'wireless');
+ foreach my $intf ($cfg->listOrigNodes($type)) {
+ my $hwid = $cfg->returnOrigValue("$type $intf hw-id");
+ next unless $hwid;
+ # TBD this could be a hash with name and path?
+ $interfaces->{$hwid} = $intf;
+ }
+ }
-finish ()
-{
- local cmd=$1 name=$2 address=$3
+ my $newname = $interfaces->{$hwaddr};
+ return $newname if ($newname);
- # The output from this program tells udev what name to give this device
- echo $name
+ # Does biosdevname have a suggestion?
+ my $biosname = `/sbin/biosdevname -i $ifname`;
+ chomp $biosname;
+ syslog(LOG_DEBUG, "biosdevname for '%s' => '%s'", $ifname, $biosname);
- # This file tells rl_system startup script how to update the Vyatta
- # config file.
- touch /tmp/${progname}_${cmd}_${name}_${address} &> /dev/null
+ if ($biosname && ($biosname ne '')) {
+ $newname = $biosname;
+ } else {
+ $newname = $ifname;
+ }
- # Remove entry for this MAC addr from the standard udev generated
- # config file, if it exists, so it doesn't rename the interface
- # out from under us. Remove the subject line plus the comment
- # line above it
- if [ -e $udev_persistent_net_rules_file ]; then
- sed -i -e "/^#/N;/${address}.*NAME/d" $udev_persistent_net_rules_file
- fi
+ $newname = find_available($interfaces, $ifname)
+ unless is_available($interfaces, $biosname);
- exit $?
+ syslog(LOG_INFO, "new name for '%s' is '%s'", $ifname, $newname);
+
+ return $newname;
}
-# Determine whether variable "ethn" conflicts with an ethernet unit
-# number that was assigned in previous runs of this script
-ethn_conflicts()
-{
- # Return value 1 (failure) means no conflicts found.
- # Return value 0 (success) means conflicts were found.
- conflicts=1
-
- echo "`date`: ethn_conflicts is checking if $ethn has conflicts" >> $log_file
- # Generate list of ethernet unit numbers assigned previously by this script
- used_ethn=""
- for filename in /tmp/vyatta_net_name* ; do
- if [ -e $filename ]; then
- # strip off everything before the unit number
- unit=${filename##*vyatta_net_name_*_eth}
- # strip off everything after the unit number
- unit=${unit%%_*}
- # add unit number from this file to the list
- used_ethn="$used_ethn $unit"
- fi
- done
-
- echo "`date`: ethn_conflicts: about to run check" >> $log_file
-
- for this_ethn in $used_ethn ; do
- if [ $ethn -eq $this_ethn ]; then
- echo "`date`: ethn $ethn conflicts with previously configured $this_ethn" >> $log_file
- conflicts=0
- break
- fi
- done
-
- echo "`date`: ethn_conflicts for ethn $ethn returns $conflicts" >> $log_file
- # return value (exit status) is true, i.e. 0, if there is a conflict
- return $conflicts
+my $LOCKF;
+sub lock_file {
+ open ($LOCKF, '>', $LOCKFILE)
+ or die "Can't open $LOCKFILE : $!";
+
+ flock ($LOCKF, LOCK_EX)
+ or die "Can't lock $LOCKFILE : $!";
+
}
+sub unlock_file {
+ close $LOCKF;
+ $LOCKF = undef;
+}
-#
-# Find an ethernet unit number that is neither listed in the config
-# file nor assigned by this script in earlier runs.
-get_free_ethn()
-{
- # list of ethernet unit numbers assigned previously by this script
- used_ethn=""
- for filename in /tmp/vyatta_net_name* ; do
- if [ -e $filename ]; then
- # strip off everything before the unit number
- unit=${filename##*vyatta_net_name_*_eth}
- # strip off everything after the unit number
- unit=${unit%%_*}
- # add unit number from this file to the list
- used_ethn="$used_ethn $unit"
- fi
- done
-
- # Counting up from 0, try to find a free ethernet unit number
- found=0
- for ((ethn_to_use=0 ; ; ethn_to_use+=1)) ; do
- found=1
- # Check to see if this one is in the config file
-
- echo "`date`: get_free_ethn: cfg_net_hwid is ${cfg_net_hwid[@]}" >> $log_file
-
- for name_hwid in ${cfg_net_hwid[@]} ; do
- name=${name_hwid%=*}
- this_ethn=${name/eth/}
- echo "`date`: get_free_ethn 1 comparing $ethn_to_use vs $this_ethn" >> $log_file
- if [ $ethn_to_use -eq $this_ethn ]; then
- found=0
- break
- fi
- done
-
- if [ $found -eq 0 ]; then
- continue
- fi
-
- echo "`date`: get_free_ethn: used_ethn is $used_ethn" >> $log_file
-
- # Check to see if this script has assigned this unit number already
- for this_ethn in $used_ethn ; do
- echo "`date`: get_free_ethn 2 comparing $ethn_to_use vs $this_ethn" >> $log_file
- if [ $ethn_to_use -eq $this_ethn ]; then
- found=0
- break
- fi
- done
-
- if [ $found -eq 1 ]; then
- break
- fi
- done
-
- # The return value
- ethn=$ethn_to_use
-
- echo "`date`: get_free_ethn found $ethn_to_use" >> $log_file
+# This script is called from udev with two arguments
+# it outputs the new name (if any) to stdout
+if ($#ARGV != 1) {
+ die "vyatta_net_name called with wrong args(%d) : %s",
+ $#ARGV, join(' ', @ARGV);
}
-#
-# Main Section
-#
-# Run with lock held to protect atomicity of access to assigned ethn file
-( flock 200
+my $ifname = $ARGV[0];
+my $hwaddr = $ARGV[1];
-touch $log_file
+lock_file;
+my $newname;
+if ( -d $VYATTACFG ) {
+ $newname = hotplug($ifname, $hwaddr);
+} else {
+ $newname = coldplug($ifname, $hwaddr);
+}
+unlock_file;
-echo "`date`: vyatta_net_name $orig_kname $attr_address" >> $log_file
+print "$newname\n" if ($newname);
-# The biosdevname program determines the "recommended" name for the NIC
-# based on information such its place in the bus topology, and whether it
-# resides on the motherboard or not. The ensures deterministic NIC naming.
-#
-if [ ! -z "$orig_kname" ]; then
- if [ -e /sbin/biosdevname ]; then
- kname=`/sbin/biosdevname -i $orig_kname`
- echo "`date`: /sbin/biosdevname maps $orig_kname to $kname" >> $log_file
- else
- echo "`date`: /sbin/biosdevname is not present on this system" >> $log_file
- kname=$orig_kname
- fi
-else
- kname=""
-fi
-
-if [ ! -f $BOOTFILE ] ; then
- cp $DEFAULT_BOOTFILE $BOOTFILE
- chgrp vyattacfg $BOOTFILE
- chmod 660 $BOOTFILE
-fi
-
-for name_hwid in ${cfg_net_hwid[@]} ; do
- name=${name_hwid%=*}
- hwid=${name_hwid#*=}
- ethn=${name/eth/}
- echo "`date`: Checking $name_hwid against $kname $attr_address" >> $log_file
-
- if [ "$hwid" == "$attr_address" ] ; then
- # The MAC addr of this interface matches an entry in the config
- # file. We mod the config file interface sub-block in case it
- # is missing.
-
- echo "`date`: finish 1: mod $name $attr_address" >> $log_file
-
- finish mod $name $attr_address
- fi
-
- if [ "$name" = "$kname" ]; then
- # The kernel name matches an entry in the config file. Save the
- # config file entry for later examination.
-
- match=$name_hwid
- fi
-done
-
-if [ -z "$kname" ]; then
- echo "`date`: Error: interface name not specified by caller" >> $log_file
- exit 1
-fi
-
-# We have not found a matching hwid in the config file. See if we can use
-# the kernel name.
-
-if [ -z "$match" ] ; then
- # The kernel interface name is not listed in the config file.
- # If the kernel's name is in the standard "ethN" format, and doesn't
- # conflict with any other name we've used, then
- # we can just go ahead and use the kernel's name. If not, then
- # we will generate a name in the standard format that does not
- # conflict with any names in the config file, or any other names
- # that we have seen.
-
- non_std_kname=${kname##eth+([0-9])}
- if [ -z "$non_std_kname" ]; then
- # kname is in standard format, so we get the unit number from it.
- ethn=${kname/eth/}
-
- # We can use this unit number unless it happens to conflict
- # with one we have already assigned.
- if ethn_conflicts ; then
- echo "`date`: kname $kname conflicts with already assigned unit" >> $log_file
- get_free_ethn
- fi
- else
- # kname is not in standard format, so we have to generate
- # a unit number
- echo "`date`: kname $kname is non-standard format" >> $log_file
- get_free_ethn
- fi
-
- echo "`date`: finish 2: add eth$ethn $attr_address" >> $log_file
-
- finish add eth$ethn $attr_address
-
-elif [ -z "${match#*=}" ] ; then
- # The config file has this interface but the sub-block is missing the hwid
- # field, so we use the kernel name. In this case, we know that the
- # kernel name is in the standard format because it matched an entry
- # in the config file, and all entries in the config file are in standard
- # format. This will cause the hwid for this NIC to be added to the
- # entry in the config file.
-
- echo "`date`: finish 3: mod $kname $attr_address" >> $log_file
-
- finish mod $kname $attr_address
-
-else
- # The config file has this interface name, but the mac address is not
- # that of this NIC. This indicates that the device is either a
- # replacement or new NIC that is being detected earlier than the device
- # configured with this name. Since we don't know which case it is,
- # we must generate a new unit number.
- get_free_ethn
-
- echo "`date`: finish 4: add eth$ethn $attr_address" >> $log_file
-
- finish add eth$ethn $attr_address
-fi
-
-# Should never get here. If this shows up in the log file, something
-# is wrong!
-echo "`date`: no finish: kname = $kname, attr_attr = $attr_address, match = $match" >> $log_file
-
-) 200> /tmp/vnn_lock
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 4
-# End:
+exit 0;
diff --git a/sysconf/65-vyatta-net.rules b/sysconf/65-vyatta-net.rules
new file mode 100644
index 00000000..1372110f
--- /dev/null
+++ b/sysconf/65-vyatta-net.rules
@@ -0,0 +1,13 @@
+# These rules use vyatta_net_name to persistently name network interfaces
+# per "hwid" association in the Vyatta configuration file.
+
+ACTION!="add", GOTO="vyatta_net_end"
+SUBSYSTEM!="net", GOTO="vyatta_net_end"
+
+# ignore the interface if a name has already been set
+NAME=="?*", GOTO="vyatta_net_end"
+
+# Do name change for ethernet and wireless devices only
+KERNEL=="eth*|wlan*", PROGRAM="vyatta_net_name %k $attr{address}", NAME="%c"
+
+LABEL="vyatta_net_end"
diff --git a/sysconf/69-vyatta-net.rules b/sysconf/69-vyatta-net.rules
deleted file mode 100644
index 9e874381..00000000
--- a/sysconf/69-vyatta-net.rules
+++ /dev/null
@@ -1,25 +0,0 @@
-# These rules use vyatta_net_name to persistently name network interfaces
-# per "hwid" association with the interface block of the vyatta config file.
-
-# note that this is actually invoked twice: once during early rcS (udev)
-# and the second time during rl-system (rescan). pre-mendocino, ACTION is
-# "add" on both invocations, so the original rule looks for "add".
-#
-# however, in mendocino, the squeeze udev performs the second invocation with
-# ACTION "change", so the original rule does not get applied on the second
-# invocation, and therefore config.boot is not updated by rl-system.
-#
-# to emulate the previous behavior, invoke vyatta_net_name for both "add" and
-# "change" for now. however, the two-pass approach should be revisited to
-# determine if it is still necessary.
-
-ACTION!="add", ACTION!="change", GOTO="vyatta_net_end"
-SUBSYSTEM!="net", GOTO="vyatta_net_end"
-
-# ignore the interface if a name has already been set
-NAME=="?*", GOTO="vyatta_net_end"
-
-# Do name change for ethernet devices only
-KERNEL=="eth*", PROGRAM="vyatta_net_name %k $attr{address}", NAME="%c"
-
-LABEL="vyatta_net_end"
diff --git a/templates/interfaces/bonding/node.def b/templates/interfaces/bonding/node.def
index 211140da..2346c490 100644
--- a/templates/interfaces/bonding/node.def
+++ b/templates/interfaces/bonding/node.def
@@ -9,9 +9,10 @@ syntax:expression: pattern $VAR(@) "^bond[0-9]+$" \
begin: if [ ! -f /sys/class/net/bonding_masters ]; then
sudo modprobe bonding max_bonds=0 miimon=250
fi
+
create: sudo sh -c "echo +$VAR(@) > /sys/class/net/bonding_masters" || exit 1
- ip link set "$VAR(@)" up
- /opt/vyatta/sbin/vyatta-link-detect $VAR(@) on
+ touch /tmp/bonding_$VAR(@).$PPID
+
delete: SLAVES=`cat /sys/class/net/$VAR(@)/bonding/slaves`;
if [ -z "$SLAVES" ]
then
@@ -20,3 +21,9 @@ delete: SLAVES=`cat /sys/class/net/$VAR(@)/bonding/slaves`;
echo "bonded interface $VAR(@) still has slaves: $SLAVES"
exit 1;
fi
+
+end: if [ -f /tmp/bonding_$VAR(@).$PPID ]
+ then rm -f /tmp/bonding_$VAR(@).$PPID
+ ip link set "$VAR(@)" up
+ /opt/vyatta/sbin/vyatta-link-detect $VAR(@) on
+ fi
diff --git a/templates/interfaces/bonding/node.tag/arp-monitor/interval/node.def b/templates/interfaces/bonding/node.tag/arp-monitor/interval/node.def
new file mode 100644
index 00000000..1b88797e
--- /dev/null
+++ b/templates/interfaces/bonding/node.tag/arp-monitor/interval/node.def
@@ -0,0 +1,5 @@
+type: u32
+default: 0
+help: ARP link monitoring frequency in milliseconds
+
+update: sudo sh -c "echo $VAR(@) >/sys/class/net/$VAR(../../@)/bonding/arp_interval"
diff --git a/templates/interfaces/bonding/node.tag/arp-monitor/node.def b/templates/interfaces/bonding/node.tag/arp-monitor/node.def
new file mode 100644
index 00000000..e1c392a7
--- /dev/null
+++ b/templates/interfaces/bonding/node.tag/arp-monitor/node.def
@@ -0,0 +1 @@
+help: ARP link monitoring parameters
diff --git a/templates/interfaces/bonding/node.tag/arp-monitor/target/node.def b/templates/interfaces/bonding/node.tag/arp-monitor/target/node.def
new file mode 100644
index 00000000..7dad4c4c
--- /dev/null
+++ b/templates/interfaces/bonding/node.tag/arp-monitor/target/node.def
@@ -0,0 +1,7 @@
+multi:
+type: ipv4
+help: IP address to use for ARP monitoring
+
+create: sudo sh -c "echo +$VAR(@) >/sys/class/net/$VAR(../../@)/bonding/arp_ip_target"
+
+delete: sudo sh -c "echo -$VAR(@) >/sys/class/net/$VAR(../../@)/bonding/arp_ip_target"
diff --git a/templates/interfaces/bonding/node.tag/hash-policy/node.def b/templates/interfaces/bonding/node.tag/hash-policy/node.def
index 54c2bb0f..842410d9 100644
--- a/templates/interfaces/bonding/node.tag/hash-policy/node.def
+++ b/templates/interfaces/bonding/node.tag/hash-policy/node.def
@@ -5,8 +5,7 @@ syntax:expression: $VAR(@) in "layer2", "layer2+3", "layer3+4" \
; "hash_policy must be layer2 layer3+4 or layer2+3"
help: Bonding transmit hash policy
-update: sudo sh -c \
- "echo $VAR(@) >/sys/class/net/$VAR(../@)/bonding/xmit_hash_policy"
+update: sudo ${vyatta_sbindir}/vyatta-bonding.pl --dev=$VAR(../@) --hash=$VAR(@)
val_help: layer2; use MAC addresses to generate the hash (802.3ad)
val_help: layer2+3; combine MAC address and IP address to make hash