summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Grennan <tgrennan@vyatta.com>2008-01-03 17:19:42 -0800
committerTom Grennan <tgrennan@vyatta.com>2008-01-03 17:19:42 -0800
commitfabea89d2586a33fb14c8e8fc489dd5fccab803d (patch)
treef58c56fedf1b375d9585f60112ef2ef17862c374
parent62e9560404415217ffef5c547e28e96ddf2505a3 (diff)
parentd5b3e4d3c413cbf1a5295e51750258d014478857 (diff)
downloadvyatta-cfg-fabea89d2586a33fb14c8e8fc489dd5fccab803d.tar.gz
vyatta-cfg-fabea89d2586a33fb14c8e8fc489dd5fccab803d.zip
Merge branch 'glendale' of http://suva.vyatta.com/vyatta-cfg into glendale
-rw-r--r--Makefile.am1
-rw-r--r--etc/default/vyatta-cfg5
-rw-r--r--scripts/VyattaConfig.pm122
-rwxr-xr-xscripts/VyattaConfigLoad.pm4
-rwxr-xr-xscripts/VyattaMisc.pm226
-rw-r--r--scripts/vyatta-irqaffin139
-rw-r--r--templates/interfaces/ethernet/node.tag/smp_affinity/node.def6
7 files changed, 396 insertions, 107 deletions
diff --git a/Makefile.am b/Makefile.am
index 733526f..7cde9aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -37,6 +37,7 @@ sbin_SCRIPTS += scripts/vyatta-save-config.pl
sbin_SCRIPTS += scripts/vyatta-load-config.pl
sbin_SCRIPTS += scripts/vyatta-cfg-notify
sbin_SCRIPTS += scripts/vyatta-interfaces.pl
+sbin_SCRIPTS += scripts/vyatta-irqaffin
share_perl5_DATA = scripts/VyattaConfig.pm
share_perl5_DATA += scripts/VyattaConfigDOMTree.pm
diff --git a/etc/default/vyatta-cfg b/etc/default/vyatta-cfg
index e560788..dfb4006 100644
--- a/etc/default/vyatta-cfg
+++ b/etc/default/vyatta-cfg
@@ -7,13 +7,14 @@ declare -x -r VYATTA_CHANGES_ONLY_DIR=${vyatta_configdir}/tmp/changes_only_$$
declare -x -r VYATTA_TEMP_CONFIG_DIR=${vyatta_configdir}/tmp/new_config_$$
declare -x -r VYATTA_CONFIG_TMP=${vyatta_configdir}/tmp/tmp_$$
declare -x -r VYATTA_CONFIG_TEMPLATE=$vyatta_cfg_templates
-declare -x -r VYATTA_EDIT_LEVEL=/
-declare -x -r VYATTA_TEMPLATE_LEVEL=/
declare -x -r VYATTA_TAG_NAME=node.tag
declare -x -r VYATTA_MOD_NAME=.modified
declare -x -r VYATTA_CFG_GROUP_NAME=vyattacfg
} 2>/dev/null || :
+declare -x VYATTA_EDIT_LEVEL=/
+declare -x VYATTA_TEMPLATE_LEVEL=/
+
# don't set level if already set
if [ -n "$VYATTA_USER_LEVEL_DIR" ]; then
return
diff --git a/scripts/VyattaConfig.pm b/scripts/VyattaConfig.pm
index 4d0a90c..6c37073 100644
--- a/scripts/VyattaConfig.pm
+++ b/scripts/VyattaConfig.pm
@@ -190,8 +190,8 @@ sub returnOrigValue {
# node is relative
sub returnValues {
my $val = returnValue(@_);
- my @values;
- if ($val) {
+ my @values = ();
+ if (defined($val)) {
@values = split("\n", $val);
}
return @values;
@@ -241,85 +241,30 @@ sub existsOrig {
# is the "node" deleted. node is relative. returns true or false
sub isDeleted {
my ($self, $node) = @_;
- my $endnode = undef;
- my $filepath = undef;
- my @nodes = ();
-
- # split the string into an array
- (@nodes) = split /\s+/, $node;
-
- # take the last node off the string
- $endnode = pop @nodes;
- # and modify it to match the whiteout name
- $endnode = ".wh.$endnode";
-
- # setup the path with the rest of the nodes
- # use the change_dir
$node =~ s/\//%2F/g;
$node =~ s/\s+/\//g;
- $filepath = "$self->{_changes_only_dir_base}$self->{_current_dir_level}/$node";
- # if the file exists, the node was deleted
- if (-f "$filepath") { return 1; }
- else { return 0; }
+ my $filepathAct
+ = "$self->{_active_dir_base}$self->{_current_dir_level}/$node";
+ my $filepathNew
+ = "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node";
+
+ if ((-e $filepathAct) && !(-e $filepathNew)) {
+ return 1;
+ }
+ return 0;
}
## listDeleted("level")
# return array of deleted nodes in the "level"
# "level" defaults to current
sub listDeleted {
- my ($self, $node) = @_;
- my @return = ();
- my $filepath = undef;
- my $curpath = undef;
- my @nodes = ();
- my @curnodes = ();
-
- # setup the entire path with the new level
- # use the change_dir
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
- $filepath = "$self->{_changes_only_dir_base}$self->{_current_dir_level}/$node/";
-
- $curpath = "$self->{_active_dir_base}$self->{_current_dir_level}/$node/";
-
- # let's see if the directory exists and find the the whiteout files
- if (! -d "$filepath") { return undef; }
- else {
- opendir DIR, "$filepath" or return undef;
- @nodes = grep !/^\.wh\.\.wh\./, grep /^\.wh./, readdir DIR;
- closedir DIR;
- }
-
- if (! -d "$curpath") {
- return undef;
- } else {
- opendir DIR, "$curpath" or return undef;
- @curnodes = grep !/^\./, readdir DIR;
- closedir DIR;
- }
-
- # get rid of the whiteout prefix
- my $dir_opq = 0;
- foreach $node (@nodes) {
- $node =~ s/^\.wh\.(.+)/$1/;
- $_ = $node;
- if (! /__dir_opaque/) {
- push @return, $node;
- } else {
- $dir_opq = 1;
- }
- }
-
- if ($dir_opq) {
- # if this node is "dir_opaque", it has been deleted and re-added.
- # add all nodes in "active" to the return list (so that they will be
- # marked "deleted"). note that if a node is also re-added, its status
- # will be changed after the listDeleted call.
- push @return, @curnodes;
- }
-
- return @return;
+ my ($self, $path) = @_;
+ my @new_nodes = $self->listNodes("$path");
+ my @orig_nodes = $self->listOrigNodes("$path");
+ my %new_hash = map { $_ => 1 } @new_nodes;
+ my @deleted = grep { !defined($new_hash{$_}) } @orig_nodes;
+ return @deleted;
}
## isChanged("node")
@@ -338,6 +283,32 @@ sub isChanged {
else { return 0; }
}
+## isChangedOrDeleted("node")
+# is the "node" changed or deleted. node is relative. returns true or false
+sub isChangedOrDeleted {
+ my ($self, $node) = @_;
+
+ $node =~ s/\//%2F/g;
+ $node =~ s/\s+/\//g;
+
+ my $filepathChg
+ = "$self->{_changes_only_dir_base}$self->{_current_dir_level}/$node";
+ if (-e $filepathChg) {
+ return 1;
+ }
+
+ my $filepathAct
+ = "$self->{_active_dir_base}$self->{_current_dir_level}/$node";
+ my $filepathNew
+ = "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node";
+
+ if ((-e $filepathAct) && !(-e $filepathNew)) {
+ return 1;
+ }
+
+ return 0;
+}
+
## isAdded("node")
# will compare the new_config_dir to the active_dir to see if the "node" has
# been added. returns true or false.
@@ -372,22 +343,21 @@ sub listNodeStatus {
my ($self, $path) = @_;
my @nodes = ();
my %nodehash = ();
- my $node = undef;
# find deleted nodes first
@nodes = $self->listDeleted("$path");
- foreach $node (@nodes) {
+ foreach my $node (@nodes) {
if ($node =~ /.+/) { $nodehash{$node} = "deleted" };
}
@nodes = ();
@nodes = $self->listNodes("$path");
- foreach $node (@nodes) {
+ foreach my $node (@nodes) {
if ($node =~ /.+/) {
#print "DEBUG VyattaConfig->listNodeStatus(): node $node\n";
+ # No deleted nodes -- added, changed, ot static only.
if ($self->isAdded("$path $node")) { $nodehash{$node} = "added"; }
elsif ($self->isChanged("$path $node")) { $nodehash{$node} = "changed"; }
- elsif ($self->isDeleted("$path $node")) { $nodehash{$node} = "deleted"; }
else { $nodehash{$node} = "static"; }
}
}
diff --git a/scripts/VyattaConfigLoad.pm b/scripts/VyattaConfigLoad.pm
index eae2946..efec951 100755
--- a/scripts/VyattaConfigLoad.pm
+++ b/scripts/VyattaConfigLoad.pm
@@ -209,7 +209,7 @@ sub findDeletedValues {
# for "multi:" nodes, need to sort the values by the original order.
my @nvals = getSortedMultiValues($new_ref, \@active_path);
if ($is_text) {
- @nvals = map { /^"(.*)"$/; $1; } @nvals;
+ @nvals = map { /^"(.*)"$/ ? $1 : $_ }@nvals;
}
my @ovals = $active_cfg->returnOrigValues('');
my %comp_hash = $active_cfg->compareValueLists(\@ovals, \@nvals);
@@ -261,7 +261,7 @@ sub findSetValues {
# for "multi:" nodes, need to sort the values by the original order.
my @nvals = getSortedMultiValues($new_ref, \@active_path);
if ($is_text) {
- @nvals = map { /^"(.*)"$/; $1; } @nvals;
+ @nvals = map { /^"(.*)"$/ ? $1 : $_ } @nvals;
}
my @ovals = $active_cfg->returnOrigValues('');
my %comp_hash = $active_cfg->compareValueLists(\@ovals, \@nvals);
diff --git a/scripts/VyattaMisc.pm b/scripts/VyattaMisc.pm
index 61c646b..45bd7d4 100755
--- a/scripts/VyattaMisc.pm
+++ b/scripts/VyattaMisc.pm
@@ -1,40 +1,68 @@
+#
+# Module: VyattaMisc.pm
+#
+# **** License ****
+# Version: VPL 1.0
+#
+# The contents of this file are subject to the Vyatta Public License
+# Version 1.0 ("License"); you may not use this file except in
+# compliance with the License. You may obtain a copy of the License at
+# http://www.vyatta.com/vpl
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2005, 2006, 2007 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Author: Marat
+# Date: 2007
+# Description:
+#
+# **** End License ****
+#
+
package VyattaMisc;
require Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(getNetAddIP, isIpAddress);
-@EXPORT_OK = qw(getNetAddIP, isIpAddress);
-
-use strict;
+@EXPORT = qw(getNetAddIP isIpAddress);
+@EXPORT_OK = qw(getNetAddIP isIpAddress);
-sub getNetAddrIP {
- my ($interface);
- ($interface) = @_;
- if ($interface eq '') {
- print STDERR "Error: No interface specified.\n";
- return undef;
- }
+use strict;
+use VyattaConfig;
- my $ifconfig_out = `ifconfig $interface`;
- $ifconfig_out =~ /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/;
- my $ip = $1;
- if ($ip eq '') {
- print STDERR "Error: Unable to determine IP address for interface \'$interface\'.\n";
- return undef;
- }
+sub getNetAddrIP {
+ my ($interface);
+ ($interface) = @_;
+ if ($interface eq '') {
+ print STDERR "Error: No interface specified.\n";
+ return undef;
+ }
- $ifconfig_out =~ /Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/;
- my $netmask = $1;
- if ($netmask eq '') {
- print STDERR "Error: Unable to determine netmask for interface \'$interface\'.\n";
- return undef;
- }
+ my $ifconfig_out = `ifconfig $interface`;
+ $ifconfig_out =~ /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/;
+ my $ip = $1;
+ if ($ip eq '') {
+ print STDERR "Error: Unable to determine IP address for interface \'$interface\'.\n";
+ return undef;
+ }
- use NetAddr::IP; # This library is available via libnetaddr-ip-perl.deb
- my $naip = new NetAddr::IP($ip, $netmask);
- return $naip;
+ $ifconfig_out =~ /Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/;
+ my $netmask = $1;
+ if ($netmask eq '') {
+ print STDERR "Error: Unable to determine netmask for interface \'$interface\'.\n";
+ return undef;
+ }
+
+ use NetAddr::IP; # This library is available via libnetaddr-ip-perl.deb
+ my $naip = new NetAddr::IP($ip, $netmask);
+ return $naip;
}
sub isIpAddress {
@@ -59,4 +87,148 @@ sub isIpAddress {
return 1;
}
+sub isClusterIP {
+ my ($vc, $ip) = @_;
+
+ if (!(defined($ip))) {
+ return 0;
+ }
+
+ my @cluster_groups = $vc->listNodes('cluster group');
+ foreach my $cluster_group (@cluster_groups) {
+ my @services = $vc->returnValues("cluster group $cluster_group service");
+ foreach my $service (@services) {
+ if ($ip eq $service) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+sub remove_ip_prefix {
+ my @addr_nets = @_;
+
+ s/\/\d+$// for @addr_nets;
+ return @addr_nets;
+}
+
+sub is_ip_in_list {
+ my ($ip, @list) = @_;
+
+ if (!defined($ip) || scalar(@list) == 0) {
+ return 0;
+ }
+
+ @list = remove_ip_prefix(@list);
+ my %list_hash = map { $_ => 1 } @list;
+ if (defined($list_hash{$ip})) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+sub get_eth_ip_addrs {
+ my ($vc, $eth_path) = @_;
+
+ my @addrs = ();
+ my @virt_addrs = ();
+
+ $vc->setLevel("interfaces ethernet $eth_path");
+ @addrs = $vc->returnValues("address");
+
+ #
+ # check for VIPs
+ #
+ $vc->setLevel("interfaces ethernet $eth_path vrrp vrrp-group");
+ my @vrrp_groups = $vc->listNodes();
+ foreach my $group (@vrrp_groups) {
+ $vc->setLevel("interfaces ethernet $eth_path vrrp vrrp-group $group");
+ @virt_addrs = $vc->returnValues("virtual-address");
+ }
+ return (@addrs, @virt_addrs);
+}
+
+sub get_tun_ip_addrs {
+ my ($vc, $tun_path) = @_;
+
+ my @addrs = ();
+ my @virt_addrs = ();
+
+ $vc->setLevel("interfaces tunnel $tun_path");
+ @addrs = $vc->returnValues("address");
+
+ #
+ # check for VIPs
+ #
+ $vc->setLevel("interfaces tunnel $tun_path vrrp vrrp-group");
+ my @vrrp_groups = $vc->listNodes();
+ foreach my $group (@vrrp_groups) {
+ $vc->setLevel("interfaces tunnel $tun_path vrrp vrrp-group $group");
+ @virt_addrs = $vc->returnValues("virtual-address");
+ }
+ return (@addrs, @virt_addrs);
+}
+
+sub get_serial_ip_addrs {
+ #
+ # Todo when serial is added
+ #
+}
+
+sub isIPinInterfaces {
+ my ($vc, $ip_addr, @interfaces) = @_;
+
+ if (!(defined($ip_addr))) {
+ return 0;
+ }
+
+ foreach my $intf (@interfaces) {
+ # regular ethernet
+ if ($intf =~ m/^eth\d+$/) {
+ my @addresses = get_eth_ip_addrs($vc, $intf);
+ if (is_ip_in_list($ip_addr, @addresses)) {
+ return 1;
+ }
+ }
+ # ethernet vlan
+ if ($intf =~ m/^eth(\d+).(\d+)$/) {
+ my $eth = "eth$1";
+ my $vif = $2;
+ my @addresses = get_eth_ip_addrs($vc, "$eth vif $vif");
+ if (is_ip_in_list($ip_addr, @addresses)) {
+ return 1;
+ }
+ }
+ # tunnel
+ if ($intf =~ m/^tun\d+$/) {
+ my @addresses = get_tun_ip_addrs($vc, $intf);
+ if (is_ip_in_list($ip_addr, @addresses)) {
+ return 1;
+ }
+ }
+ # serial
+ if ($intf =~ m/^wan(\d+).(\d+)$/) {
+ my @addresses = get_serial_ip_addrs($vc, $intf);
+ if (is_ip_in_list($ip_addr, @addresses)) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+sub isClusteringEnabled {
+ my ($vc) = @_;
+
+ if ($vc->exists('cluster')) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
return 1;
diff --git a/scripts/vyatta-irqaffin b/scripts/vyatta-irqaffin
new file mode 100644
index 0000000..6650175
--- /dev/null
+++ b/scripts/vyatta-irqaffin
@@ -0,0 +1,139 @@
+#!/bin/bash
+#
+# CLI back-end script to manipulate NIC interrupt CPU affinity.
+#
+# Provides sub-commands to:
+# - Check the validity of an interface name and affinity mask value
+# - Set the affinity mask to the IRQ being used by an interface
+# - Reset the affinity mask of the IRQ being used by an interface to the
+# system default value of all-ones.
+# - Print the affinity mask of the IRQ being used by an interface
+#
+
+# The default "all-ones" IRQ affinity mask. Used in the "reset" sub-command.
+DEFAULT_MASK=ffff
+
+# Max number of hex characters in an IRQ affinity mask. Support up to 16 CPUs.
+MAX_MASK=4
+
+print_usage()
+{
+ echo "Usage:"
+ echo -e "\t$0 check <ifname> <mask>"
+ echo -e "\t$0 set <ifname> <mask>"
+ echo -e "\t$0 reset <ifname>"
+ echo -e "\t$0 print <ifname>"
+}
+
+get_irqnum()
+{
+ irqnum=`find /proc/irq -name $1 -print | awk -F / '{ print $4 }'`
+ if [ -z "$irqnum" ]; then
+ echo "Invalid interface name: $1"
+ return 1
+ fi
+ return 0
+}
+
+
+get_mask()
+{
+ mask=$1
+ # mask must be a short hex value
+ if [ ${#mask} -gt $MAX_MASK ]; then
+ echo "mask too long: ${#2} characters."
+ return 1
+ fi
+
+ # strip out all the hex digits
+ exmask=`echo $mask | sed -e s/[0-9a-f]//g`
+
+ # if anything is left, its not hex
+ if [ ! -z "$exmask" ]; then
+ echo "Invalid characters in hex mask: $exmask"
+ return 1
+ fi
+ return 0
+}
+
+case "$1" in
+ check)
+ if [ $# -ne 3 ]; then
+ print_usage
+ exit 1
+ fi
+
+ if ! get_irqnum $2 ; then
+ exit 1
+ fi
+
+ if ! get_mask $3 ; then
+ exit 1
+ fi
+ exit 0
+ ;;
+
+ set)
+ if [ $# -ne 3 ]; then
+ print_usage
+ exit 1
+ fi
+ if ! get_irqnum $2 ; then
+ exit 1
+ fi
+
+ if ! get_mask $3 ; then
+ exit 1
+ fi
+
+ echo $mask > /proc/irq/$irqnum/smp_affinity
+
+ if [ $? -ne 0 ]; then
+ echo "Couldn't assign smp_affinity. Exit status: $?"
+ exit 1
+ fi
+ ;;
+
+ reset)
+ if [ $# -ne 2 ]; then
+ print_usage
+ exit 1
+ fi
+ if ! get_irqnum $2 ; then
+ exit 1
+ fi
+
+ echo $DEFAULT_MASK > /proc/irq/$irqnum/smp_affinity
+ if [ $? -ne 0 ]; then
+ echo "Couldn't assign smp_affinity. Exit status: $?"
+ exit 1
+ fi
+ ;;
+
+
+ print)
+ if [ $# -ne 2 ]; then
+ print_usage
+ exit 1
+ fi
+ if ! get_irqnum $2 ; then
+ exit 1
+ fi
+
+ mask=`cat /proc/irq/$irqnum/smp_affinity`
+
+ if [ -z $mask ]; then
+ echo "Couldn't get smp_affinity for interface $2, irq $irqnum"
+ exit 1
+ fi
+
+ echo "Interface $2 is using IRQ: $irqnum"
+ echo "SMP affinity mask for IRQ $irqnum is: $mask"
+ ;;
+
+ *)
+ print_usage
+ exit 1
+ ;;
+
+esac
diff --git a/templates/interfaces/ethernet/node.tag/smp_affinity/node.def b/templates/interfaces/ethernet/node.tag/smp_affinity/node.def
new file mode 100644
index 0000000..b24be8c
--- /dev/null
+++ b/templates/interfaces/ethernet/node.tag/smp_affinity/node.def
@@ -0,0 +1,6 @@
+multi:
+type: txt
+help: "Set CPU interrupt affinity mask for this interface"
+syntax: exec "/opt/vyatta/sbin/vyatta-irqaffin check $(../@) $(@)"
+create: "sudo /opt/vyatta/sbin/vyatta-irqaffin set $(../@) $(@)"; "Error setting CPU affinity mask $(@) on interface $(../@)"
+delete: "sudo /opt/vyatta/sbin/vyatta-irqaffin reset (../@)"; "Error deleting CPU affinity mask on interface $(../@)"