diff options
author | Daniil Baturin <daniil@baturin.org> | 2018-10-28 19:30:06 +0100 |
---|---|---|
committer | Daniil Baturin <daniil@baturin.org> | 2018-10-28 19:30:06 +0100 |
commit | 37db2e326b290c9c756eecfe08c464e8b627a682 (patch) | |
tree | caf104e0fda4f23f829b2945a316c7da2a6554f7 | |
parent | 13a053c14c402fa0f7be174adbe9cfa53e811369 (diff) | |
parent | 6daba1eb14430aa02f8f56614188a598b383c8ef (diff) | |
download | vyatta-cfg-system-37db2e326b290c9c756eecfe08c464e8b627a682.tar.gz vyatta-cfg-system-37db2e326b290c9c756eecfe08c464e8b627a682.zip |
Merge branch 'current' into crux
Conflicts:
Makefile.am
debian/changelog
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | cfg-version/dhcp-relay@1 | 0 | ||||
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | etc/init.d/ec2-vyos-init | 2 | ||||
-rwxr-xr-x | scripts/vyatta-dhcpv6-client.pl | 60 | ||||
-rwxr-xr-x | scripts/vyatta-interfaces.pl | 835 | ||||
-rw-r--r-- | sysconf/vyatta-sysctl.conf | 3 | ||||
-rw-r--r-- | templates/interfaces/bridge/node.def | 6 | ||||
-rw-r--r-- | templates/interfaces/tunnel/node.tag/parameters/ip/bridge-group/bridge/node.def | 6 | ||||
-rw-r--r-- | templates/system/login/user/node.def | 1 |
10 files changed, 489 insertions, 431 deletions
diff --git a/Makefile.am b/Makefile.am index b9620f85..0c513a49 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,6 +121,7 @@ curver_DATA += cfg-version/system@9 curver_DATA += cfg-version/broadcast-relay@1 curver_DATA += cfg-version/mdns@1 curver_DATA += cfg-version/dhcp-server@5 +curver_DATA += cfg-version/dhcp-relay@1 curver_DATA += cfg-version/ssh@1 cpiop = find . ! -regex '\(.*~\|.*\.bak\|.*\.swp\|.*\#.*\#\)' -print0 | \ diff --git a/cfg-version/dhcp-relay@1 b/cfg-version/dhcp-relay@1 new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/cfg-version/dhcp-relay@1 diff --git a/debian/changelog b/debian/changelog index cac0a8d9..bd4efe61 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -vyatta-cfg-system (1.2.0-1) stable; urgency=medium +vyatta-cfg-system (0.20.44+vyos2+current15) unstable; urgency=medium - * New branch. + * Virtio network card, no info (maybe not fully supported?) - -- Daniil Baturin <daniil@baturin.org> Fri, 28 Sep 2018 21:45:32 +0200 + -- hagbard <vyosdev@derith.de> Mon, 15 Oct 2018 14:27:24 -0700 vyatta-cfg-system (0.20.44+vyos2+current14) unstable; urgency=medium diff --git a/etc/init.d/ec2-vyos-init b/etc/init.d/ec2-vyos-init index 271648bc..78d7be90 100644 --- a/etc/init.d/ec2-vyos-init +++ b/etc/init.d/ec2-vyos-init @@ -1,7 +1,7 @@ #!/bin/bash ### BEGIN INIT INFO # Provides: ec2-vyos-init -# Required-Start: vyatta-router +# Required-Start: vyos-router # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: diff --git a/scripts/vyatta-dhcpv6-client.pl b/scripts/vyatta-dhcpv6-client.pl index 74cc4db2..c0b4cfeb 100755 --- a/scripts/vyatta-dhcpv6-client.pl +++ b/scripts/vyatta-dhcpv6-client.pl @@ -38,7 +38,7 @@ sub gen_conf_file { my $FD_WR; open($FD_WR, '>', $conffile) - or die "Can't write config file: $conffile : $!\n"; + or die "Can't write config file: $conffile : $!\n"; my $date = localtime; my $user = getpwuid($<); @@ -78,19 +78,19 @@ sub usage { # Main Section # -my $start_flag; # Start the daemon -my $stop_flag; # Stop the daemon and delete all config files -my $release_flag; # Stop the daemon, but leave config file -my $renew_flag; # Re-start the daemon. Functionally same as start_flag +my $start_flag; # Start the daemon +my $stop_flag; # Stop the daemon and delete all config files +my $release_flag; # Stop the daemon, but leave config file +my $renew_flag; # Re-start the daemon. Functionally same as start_flag my $ifname; my $temporary; my $params_only; GetOptions("start" => \$start_flag, - "stop" => \$stop_flag, - "release" => \$release_flag, - "renew" => \$renew_flag, - "ifname=s" => \$ifname, + "stop" => \$stop_flag, + "release" => \$release_flag, + "renew" => \$renew_flag, + "ifname=s" => \$ifname, "temporary" => \$temporary, "parameters-only" => \$params_only ) or usage(); @@ -105,30 +105,30 @@ my $cmdname = "/sbin/dhclient"; if ($release_flag) { die "DHCPv6 client is not configured on interface $ifname.\n" - unless (-e $conffile); + unless (-e $conffile); die "DHCPv6 client is already released on interface $ifname.\n" - unless (-e $pidfile); + unless (-e $pidfile); } if ($renew_flag) { die "DHCPv6 client is not configured on interface $ifname.\n" - unless (-e $conffile); + unless (-e $conffile); } -if (defined($stop_flag)|| defined ($release_flag)) { +if (defined($stop_flag) || defined ($release_flag)) { # Stop dhclient -6 on $ifname printf("Stopping daemon...\n"); - system ("$cmdname -6 -nw -cf $conffile -pf $pidfile -lf $leasefile -x $ifname"); + system("$cmdname -6 -cf $conffile -pf $pidfile -lf $leasefile -x $ifname"); # Delete files it leaves behind... printf("Deleting related files...\n"); unlink($pidfile); if (defined $stop_flag) { - # If just releasing, leave the config file around as a flag that - # DHCPv6 remains configured on this interface. - unlink($conffile); + # If just releasing, leave the config file around as a flag that + # DHCPv6 remains configured on this interface. + unlink($conffile); } } @@ -142,6 +142,30 @@ if (defined($start_flag) || defined ($renew_flag)) { printf("Stopping old daemon...\n"); system("$cmdname -6 -pf $pidfile -x $ifname"); + # Wait for IPv6 duplicate address detection to finish, dhclient won't start otherwise + # https://phabricator.vyos.net/T903 + for (my $attempt_count = 0; $attempt_count <= 60; $attempt_count++) { + # Check for any non-tentative addresses (exit code 0 if any exist, 1 otherwise) + if (system("test -n \"\$(ip -6 -o addr show dev eth0 scope link -tentative)\"") != 0) { + # No non-tentative address found, sleep and retry or exit + if ($attempt_count == 0) { + print "Duplicate address detection incomplete, waiting\n" + } + + if ($attempt_count < 60) { + sleep(1); + next; + } else { + print "Error: No non-tentative address was found for interface $ifname\n"; + exit 1; + } + } else { + # Address found, exit loop + last; + } + } + + if (defined($temporary) && defined($params_only)) { print "Error: temporary and parameters-only options are mutually exclusive!\n"; exit 1; @@ -152,5 +176,5 @@ if (defined($start_flag) || defined ($renew_flag)) { printf("Starting new daemon...\n"); exec "$cmdname -6 $temp_opt $po_opt -nw -cf $conffile -pf $pidfile -lf $leasefile $ifname" - or die "Can't exec $cmdname"; + or die "Can't exec $cmdname"; } diff --git a/scripts/vyatta-interfaces.pl b/scripts/vyatta-interfaces.pl index aa802b97..d0e37a2d 100755 --- a/scripts/vyatta-interfaces.pl +++ b/scripts/vyatta-interfaces.pl @@ -33,8 +33,8 @@ use lib "/opt/vyatta/share/perl5/"; use Vyatta::Config; use Vyatta::Misc qw(generate_dhclient_intf_files - getInterfaces getIP get_sysfs_value - is_address_enabled is_dhcp_enabled is_ip_v4_or_v6); + getInterfaces getIP get_sysfs_value + is_address_enabled is_dhcp_enabled is_ip_v4_or_v6); use Vyatta::File qw(touch); use Vyatta::Interface; @@ -44,7 +44,7 @@ use strict; use warnings; my $dhcp_daemon = '/sbin/dhclient'; -my $ETHTOOL = '/sbin/ethtool'; +my $ETHTOOL = '/sbin/ethtool'; my ($dev, $mac, $mac_update); my %skip_interface; @@ -53,234 +53,234 @@ my ($check_up, $dhcp_command, $allowed_speed); my (@speed_duplex, @addr_commit, @check_speed, @offload_option); sub usage { - print <<EOF; + print <<EOF; Usage: $0 --dev=<interface> --check=<type> - $0 --dev=<interface> --warn - $0 --dev=<interface> --valid-mac=<aa:aa:aa:aa:aa:aa> - $0 --dev=<interface> --valid-addr-commit={addr1 addr2 ...} - $0 --dev=<interface> --speed-duplex=speed,duplex - $0 --dev=<interface> --check-speed=speed,duplex - $0 --dev=<interface> --allowed-speed - $0 --dev=<interface> --isup - $0 --dev=<interface> --offload-option={tcp-segmention,udp-fragmentation} {value} - $0 --dev=<interface> --offload-option={generic-segmentation,generic-receive} {value} - $0 --dev=<interface> --offload-option={scatter-gather} {value} - $0 --show=<type> + $0 --dev=<interface> --warn + $0 --dev=<interface> --valid-mac=<aa:aa:aa:aa:aa:aa> + $0 --dev=<interface> --valid-addr-commit={addr1 addr2 ...} + $0 --dev=<interface> --speed-duplex=speed,duplex + $0 --dev=<interface> --check-speed=speed,duplex + $0 --dev=<interface> --allowed-speed + $0 --dev=<interface> --isup + $0 --dev=<interface> --offload-option={tcp-segmention,udp-fragmentation} {value} + $0 --dev=<interface> --offload-option={generic-segmentation,generic-receive} {value} + $0 --dev=<interface> --offload-option={scatter-gather} {value} + $0 --show=<type> EOF - exit 1; + exit 1; } GetOptions( - "valid-addr-commit=s{,}" => \@addr_commit, - "dev=s" => \$dev, - "valid-mac=s" => \$mac, - "set-mac=s" => \$mac_update, - "dhcp=s" => \$dhcp_command, - "check=s" => \$check_name, - "show=s" => \$show_names, - "skip=s" => sub {$skip_interface{$_[1]} = 1}, - "vif=s" => \$vif_name, - "warn" => \$warn_name, - "isup" => \$check_up, - "speed-duplex=s{2}" => \@speed_duplex, - "check-speed=s{2}" => \@check_speed, - "allowed-speed" => \$allowed_speed, - "offload-option=s{2}" => \@offload_option, + "valid-addr-commit=s{,}" => \@addr_commit, + "dev=s" => \$dev, + "valid-mac=s" => \$mac, + "set-mac=s" => \$mac_update, + "dhcp=s" => \$dhcp_command, + "check=s" => \$check_name, + "show=s" => \$show_names, + "skip=s" => sub {$skip_interface{$_[1]} = 1}, + "vif=s" => \$vif_name, + "warn" => \$warn_name, + "isup" => \$check_up, + "speed-duplex=s{2}" => \@speed_duplex, + "check-speed=s{2}" => \@check_speed, + "allowed-speed" => \$allowed_speed, + "offload-option=s{2}" => \@offload_option, ) or usage(); is_valid_addr_commit($dev, @addr_commit) if (@addr_commit); -is_valid_mac($mac, $dev) if ($mac); -update_mac($mac_update, $dev) if ($mac_update); -dhcp($dhcp_command, $dev) if ($dhcp_command); -is_valid_name($check_name, $dev) if ($check_name); -exists_name($dev) if ($warn_name); -show_interfaces($show_names) if ($show_names); -is_up($dev) if ($check_up); -set_speed_duplex($dev, @speed_duplex) if (@speed_duplex); -check_speed_duplex($dev, @check_speed) if (@check_speed); -allowed_speed($dev) if ($allowed_speed); +is_valid_mac($mac, $dev) if ($mac); +update_mac($mac_update, $dev) if ($mac_update); +dhcp($dhcp_command, $dev) if ($dhcp_command); +is_valid_name($check_name, $dev) if ($check_name); +exists_name($dev) if ($warn_name); +show_interfaces($show_names) if ($show_names); +is_up($dev) if ($check_up); +set_speed_duplex($dev, @speed_duplex) if (@speed_duplex); +check_speed_duplex($dev, @check_speed) if (@check_speed); +allowed_speed($dev) if ($allowed_speed); set_offload_option($dev, @offload_option) if (@offload_option); exit 0; sub is_ip_configured { - my ($intf, $ip) = @_; - my $found = grep {$_ eq $ip} Vyatta::Misc::getIP($intf); - return ($found > 0); + my ($intf, $ip) = @_; + my $found = grep {$_ eq $ip} Vyatta::Misc::getIP($intf); + return ($found > 0); } sub is_ipv4 { - return index($_[0],':') < 0; + return index($_[0],':') < 0; } sub is_up { - my $name = shift; - my $intf = new Vyatta::Interface($name); + my $name = shift; + my $intf = new Vyatta::Interface($name); - die "Unknown interface type for $name" unless $intf; + die "Unknown interface type for $name" unless $intf; - exit 0 if ($intf->up()); - exit 1; + exit 0 if ($intf->up()); + exit 1; } sub dhcp_write_file { - my ($file, $data) = @_; + my ($file, $data) = @_; - open(my $fh, '>', $file) || die "Couldn't open $file - $!"; - print $fh $data; - close $fh; + open(my $fh, '>', $file) || die "Couldn't open $file - $!"; + print $fh $data; + close $fh; } sub dhcp_conf_header { - my $output; + my $output; - my $date = `date`; - chomp $date; - $output = "#\n# autogenerated by vyatta-interfaces.pl on $date\n#\n"; - return $output; + my $date = `date`; + chomp $date; + $output = "#\n# autogenerated by vyatta-interfaces.pl on $date\n#\n"; + return $output; } sub get_hostname { - my $config = new Vyatta::Config; - $config->setLevel("system"); - return $config->returnValue("host-name"); + my $config = new Vyatta::Config; + $config->setLevel("system"); + return $config->returnValue("host-name"); } sub is_domain_name_set { - my $config = new Vyatta::Config; - $config->setLevel("system"); - return $config->returnValue("domain-name"); + my $config = new Vyatta::Config; + $config->setLevel("system"); + return $config->returnValue("domain-name"); } sub get_mtu { - my $name = shift; - my $intf = new Vyatta::Interface($name); - return $intf->mtu(); + my $name = shift; + my $intf = new Vyatta::Interface($name); + return $intf->mtu(); } sub dhcp_update_config { - my ($conf_file, $intf) = @_; + my ($conf_file, $intf) = @_; - my $output = dhcp_conf_header(); - my $hostname = get_hostname(); + my $output = dhcp_conf_header(); + my $hostname = get_hostname(); - $output .= "interface \"$intf\" {\n"; - if (defined($hostname)) { - $output .= "\tsend host-name \"$hostname\";\n"; - } - $output .= "\trequest subnet-mask, broadcast-address, routers, domain-name-servers"; - my $domainname = is_domain_name_set(); - if (!defined($domainname)) { - $output .= ", domain-name"; - } + $output .= "interface \"$intf\" {\n"; + if (defined($hostname)) { + $output .= "\tsend host-name \"$hostname\";\n"; + } + $output .= "\trequest subnet-mask, broadcast-address, routers, domain-name-servers"; + my $domainname = is_domain_name_set(); + if (!defined($domainname)) { + $output .= ", domain-name"; + } - my $mtu = get_mtu($intf); - $output .= ", interface-mtu" unless $mtu; + my $mtu = get_mtu($intf); + $output .= ", interface-mtu" unless $mtu; - $output .= ";\n"; - $output .= "}\n\n"; + $output .= ";\n"; + $output .= "}\n\n"; - dhcp_write_file($conf_file, $output); + dhcp_write_file($conf_file, $output); } # Is interface disabled in configuration (only valid in config mode) sub is_intf_disabled { - my $name = shift; - my $intf = new Vyatta::Interface($name); - $intf or die "Unknown interface name/type: $name\n"; + my $name = shift; + my $intf = new Vyatta::Interface($name); + $intf or die "Unknown interface name/type: $name\n"; - my $config = new Vyatta::Config; - $config->setLevel($intf->path()); + my $config = new Vyatta::Config; + $config->setLevel($intf->path()); - return $config->exists("disable"); + return $config->exists("disable"); } sub run_dhclient { - my ($intf, $op_mode) = @_; + my ($intf, $op_mode) = @_; - my ($intf_config_file, $intf_process_id_file, $intf_leases_file)= generate_dhclient_intf_files($intf); + my ($intf_config_file, $intf_process_id_file, $intf_leases_file)= generate_dhclient_intf_files($intf); - # perform config mode actions if not called from op-mode - if (!defined $op_mode) { - dhcp_update_config($intf_config_file, $intf); - return if is_intf_disabled($intf); - } + # perform config mode actions if not called from op-mode + if (!defined $op_mode) { + dhcp_update_config($intf_config_file, $intf); + return if is_intf_disabled($intf); + } - my $cmd = "$dhcp_daemon -pf $intf_process_id_file -x $intf 2> /dev/null; rm -f $intf_process_id_file 2> /dev/null;"; - $cmd .= "$dhcp_daemon -q -nw -cf $intf_config_file -pf $intf_process_id_file -lf $intf_leases_file $intf 2> /dev/null &"; + my $cmd = "$dhcp_daemon -pf $intf_process_id_file -x $intf 2> /dev/null; rm -f $intf_process_id_file 2> /dev/null;"; + $cmd .= "$dhcp_daemon -q -nw -cf $intf_config_file -pf $intf_process_id_file -lf $intf_leases_file $intf 2> /dev/null &"; - # adding & at the end to make the process into a daemon immediately - system($cmd) == 0 - or warn "start $dhcp_daemon failed: $?\n"; + # adding & at the end to make the process into a daemon immediately + system($cmd) == 0 + or warn "start $dhcp_daemon failed: $?\n"; } sub stop_dhclient { - my ($intf, $op_mode) = @_; - - # perform config mode actions if not called from op-mode - if (!defined $op_mode) { - return if is_intf_disabled($intf); - } - - my ($intf_config_file, $intf_process_id_file, $intf_leases_file)= generate_dhclient_intf_files($intf); - my $release_cmd = "$dhcp_daemon -q -cf $intf_config_file -pf $intf_process_id_file -lf $intf_leases_file -r $intf 2> /dev/null;"; - $release_cmd .= "rm -f $intf_process_id_file 2> /dev/null"; - system($release_cmd) == 0 - or warn "stop $dhcp_daemon failed: $?\n"; + my ($intf, $op_mode) = @_; + + # perform config mode actions if not called from op-mode + if (!defined $op_mode) { + return if is_intf_disabled($intf); + } + + my ($intf_config_file, $intf_process_id_file, $intf_leases_file)= generate_dhclient_intf_files($intf); + my $release_cmd = "$dhcp_daemon -q -cf $intf_config_file -pf $intf_process_id_file -lf $intf_leases_file -r $intf 2> /dev/null;"; + $release_cmd .= "rm -f $intf_process_id_file 2> /dev/null"; + system($release_cmd) == 0 + or warn "stop $dhcp_daemon failed: $?\n"; } sub update_mac { - my ($mac, $name) = @_; - my $intf = new Vyatta::Interface($name); - $intf or die "Unknown interface name/type: $name\n"; - - # maybe nothing needs to change - my $oldmac = $intf->hw_address(); - exit 0 if (lc($oldmac) eq lc($mac)); - - # try the direct approach - if (system("sudo ip link set $name address $mac") == 0) { - exit 0; - } elsif ($intf->up()) { - - # some hardware can not change MAC address if up - system "sudo ip link set $name down" - and die "Could not set $name down\n"; - system "sudo ip link set $name address $mac" - and die "Could not set $name address\n"; - system "sudo ip link set $name up" - and die "Could not set $name up\n"; - } else { - die "Could not set mac address for $name\n"; - } + my ($mac, $name) = @_; + my $intf = new Vyatta::Interface($name); + $intf or die "Unknown interface name/type: $name\n"; + + # maybe nothing needs to change + my $oldmac = $intf->hw_address(); + exit 0 if (lc($oldmac) eq lc($mac)); + # try the direct approach + if (system("sudo ip link set $name address $mac") == 0) { exit 0; + } elsif ($intf->up()) { + + # some hardware can not change MAC address if up + system "sudo ip link set $name down" + and die "Could not set $name down\n"; + system "sudo ip link set $name address $mac" + and die "Could not set $name address\n"; + system "sudo ip link set $name up" + and die "Could not set $name up\n"; + } else { + die "Could not set mac address for $name\n"; + } + + exit 0; } sub is_vrrp_mac { - my @octets = @_; - return 1 if ( hex($octets[0]) == 0 - && hex($octets[1]) == 0 - && hex($octets[2]) == 94 - && hex($octets[3]) == 0 - && hex($octets[4]) == 1); - return 0; + my @octets = @_; + return 1 if ( hex($octets[0]) == 0 + && hex($octets[1]) == 0 + && hex($octets[2]) == 94 + && hex($octets[3]) == 0 + && hex($octets[4]) == 1); + return 0; } sub is_valid_mac { - my ($mac, $intf) = @_; - my @octets = split /:/, $mac; + my ($mac, $intf) = @_; + my @octets = split /:/, $mac; - ($#octets == 5) or die "Error: wrong number of octets: $#octets\n"; + ($#octets == 5) or die "Error: wrong number of octets: $#octets\n"; - ((hex($octets[0]) & 1) == 0) or die "Error: $mac is a multicast address\n"; + ((hex($octets[0]) & 1) == 0) or die "Error: $mac is a multicast address\n"; - is_vrrp_mac(@octets) and die "Error: $mac is a vrrp mac address\n"; + is_vrrp_mac(@octets) and die "Error: $mac is a vrrp mac address\n"; - my $sum = 0; - $sum += hex($_) foreach @octets; - ($sum != 0) or die "Error: zero is not a valid address\n"; + my $sum = 0; + $sum += hex($_) foreach @octets; + ($sum != 0) or die "Error: zero is not a valid address\n"; - exit 0; + exit 0; } # Validate the set of address values configured on an interface at commit @@ -288,340 +288,367 @@ sub is_valid_mac { # 1. Interface may not be part of bridge or bonding group # 2. Can not have both DHCP and a static IPv4 address. sub is_valid_addr_commit { - my ($ifname, @addrs) = @_; - my $intf = new Vyatta::Interface($ifname); - $intf or die "Unknown interface name/type: $ifname\n"; - - my $config = new Vyatta::Config; - $config->setLevel($intf->path()); + my ($ifname, @addrs) = @_; + my $intf = new Vyatta::Interface($ifname); + $intf or die "Unknown interface name/type: $ifname\n"; - my $bridge = $config->returnValue("bridge-group bridge"); - die "Can't configure address on interface that is port of bridge.\n" - if (defined($bridge)); + my $config = new Vyatta::Config; + $config->setLevel($intf->path()); - my $bond = $config->returnValue("bond-group"); - die "Can't configure address on interface that is slaved to bonding interface.\n" - if (defined($bond)); + my $bridge = $config->returnValue("bridge-group bridge"); + die "Can't configure address on interface that is port of bridge.\n" + if (defined($bridge)); - my $addrmap = Vyatta::Interface::get_cfg_addresses(); + my $bond = $config->returnValue("bond-group"); + die "Can't configure address on interface that is slaved to bonding interface.\n" + if (defined($bond)); - my ($dhcp, $static_v4); - foreach my $addr (@addrs) { - next if ($addr eq 'dhcpv6'); + my $addrmap = Vyatta::Interface::get_cfg_addresses(); - if ($addr eq 'dhcp') { - $dhcp = 1; - next; - } + my ($dhcp, $static_v4); + foreach my $addr (@addrs) { + next if ($addr eq 'dhcpv6'); - my $intfs = $addrmap->{$addr}; - if ($intfs && scalar(@{$intfs}) > 1) { - die "Duplicate address $addr used on interfaces: ",join(',', @${intfs}), "\n"; - } + if ($addr eq 'dhcp') { + $dhcp = 1; + next; + } - $static_v4 = 1 - if (is_ipv4($addr)); + my $intfs = $addrmap->{$addr}; + if ($intfs && scalar(@{$intfs}) > 1) { + die "Duplicate address $addr used on interfaces: ",join(',', @${intfs}), "\n"; } - die "Can't configure static IPv4 address and DHCP on the same interface.\n" - if ($static_v4 && $dhcp); + $static_v4 = 1 + if (is_ipv4($addr)); + } - exit 0; + die "Can't configure static IPv4 address and DHCP on the same interface.\n" + if ($static_v4 && $dhcp); + + exit 0; } # Is interface currently in admin down state? sub is_intf_down { - my $name = shift; - my $intf = new Vyatta::Interface($name); + my $name = shift; + my $intf = new Vyatta::Interface($name); - return 1 unless $intf; - return !$intf->up(); + return 1 unless $intf; + return !$intf->up(); } sub dhcp { - my ($request, $intf) = @_; - - die "$intf is not using DHCP to get an IP address\n" - unless ($request eq 'start' || is_dhcp_enabled($intf)); - - die "$intf is disabled.\n" - if ($request ne 'stop' && is_intf_down($intf)); - - my $tmp_dhclient_dir = '/var/run/vyatta/dhclient/'; - my $release_file = $tmp_dhclient_dir . 'dhclient_release_' . $intf; - if ($request eq "release") { - die "IP address for $intf has already been released.\n" - if (-e $release_file); - - print "Releasing DHCP lease on $intf ...\n"; - stop_dhclient($intf, 'op_mode'); - mkdir($tmp_dhclient_dir) if (!-d $tmp_dhclient_dir); - touch($release_file); - } elsif ($request eq "renew") { - print "Renewing DHCP lease on $intf ...\n"; - run_dhclient($intf, 'op_mode'); - unlink($release_file); - } elsif ($request eq "start") { - print "Starting DHCP client on $intf ...\n"; - touch("/var/lib/dhcp/$intf"); - run_dhclient($intf); - } elsif ($request eq "stop") { - print "Stopping DHCP client on $intf ...\n"; - stop_dhclient($intf); - unlink("/var/lib/dhcp/dhclient_$intf\_lease"); - unlink("/var/lib/dhcp/$intf"); - unlink("/var/run/vyatta/dhclient/dhclient_release_$intf"); - unlink("/var/lib/dhcp/dhclient_$intf\.conf"); - } else { - die "Unknown DHCP request: $request\n"; - } - - exit 0; + my ($request, $intf) = @_; + + die "$intf is not using DHCP to get an IP address\n" + unless ($request eq 'start' || is_dhcp_enabled($intf)); + + die "$intf is disabled.\n" + if ($request ne 'stop' && is_intf_down($intf)); + + my $tmp_dhclient_dir = '/var/run/vyatta/dhclient/'; + my $release_file = $tmp_dhclient_dir . 'dhclient_release_' . $intf; + if ($request eq "release") { + die "IP address for $intf has already been released.\n" + if (-e $release_file); + + print "Releasing DHCP lease on $intf ...\n"; + stop_dhclient($intf, 'op_mode'); + mkdir($tmp_dhclient_dir) if (!-d $tmp_dhclient_dir); + touch($release_file); + } elsif ($request eq "renew") { + print "Renewing DHCP lease on $intf ...\n"; + run_dhclient($intf, 'op_mode'); + unlink($release_file); + } elsif ($request eq "start") { + print "Starting DHCP client on $intf ...\n"; + touch("/var/lib/dhcp/$intf"); + run_dhclient($intf); + } elsif ($request eq "stop") { + print "Stopping DHCP client on $intf ...\n"; + stop_dhclient($intf); + unlink("/var/lib/dhcp/dhclient_$intf\_lease"); + unlink("/var/lib/dhcp/$intf"); + unlink("/var/run/vyatta/dhclient/dhclient_release_$intf"); + unlink("/var/lib/dhcp/dhclient_$intf\.conf"); + } else { + die "Unknown DHCP request: $request\n"; + } + + exit 0; } sub is_valid_name { - my ($type, $name) = @_; - die "Missing --dev argument\n" unless $name; + my ($type, $name) = @_; + die "Missing --dev argument\n" unless $name; - my $intf = new Vyatta::Interface($name); - die "$name does not match any known interface name type\n" - unless $intf; + my $intf = new Vyatta::Interface($name); + die "$name does not match any known interface name type\n" + unless $intf; - my $vif = $intf->vif(); - die "$name is the name of VIF interface\n","Need to use \"interface ",$intf->physicalDevice()," vif $vif\"\n" - if $vif; + my $vif = $intf->vif(); + die "$name is the name of VIF interface\n","Need to use \"interface ",$intf->physicalDevice()," vif $vif\"\n" + if $vif; - die "$name is a ", $intf->type(), " interface not an $type interface\n" - if ($type ne 'all' and $intf->type() ne $type); + die "$name is a ", $intf->type(), " interface not an $type interface\n" + if ($type ne 'all' and $intf->type() ne $type); - die "$type interface $name does not exist on system\n" - unless grep {$name eq $_} getInterfaces(); + die "$type interface $name does not exist on system\n" + unless grep {$name eq $_} getInterfaces(); - exit 0; + exit 0; } sub exists_name { - my $name = shift; - die "Missing --dev argument\n" unless $name; + my $name = shift; + die "Missing --dev argument\n" unless $name; - warn "interface $name does not exist on system\n" - unless grep {$name eq $_} getInterfaces(); - exit 0; + warn "interface $name does not exist on system\n" + unless grep {$name eq $_} getInterfaces(); + exit 0; } # generate one line with all known interfaces (for allowed) sub show_interfaces { - my $type = shift; - my @interfaces = getInterfaces(); - my @match; - - foreach my $name (@interfaces) { - my $intf = new Vyatta::Interface($name); - next unless $intf; # skip unknown types - next if $skip_interface{$name}; - next unless ($type eq 'all' || $type eq $intf->type()); - if ($intf->vrid()){ - push @match, $name; # add all vrrp interfaces - } elsif ($vif_name) { - next unless $intf->vif(); - push @match, $intf->vif() - if ($vif_name eq $intf->physicalDevice()); - } else { - push @match, $name - unless $intf->vif() - and $type ne 'all'; - } + my $type = shift; + my @interfaces = getInterfaces(); + my @match; + + foreach my $name (@interfaces) { + my $intf = new Vyatta::Interface($name); + next unless $intf; # skip unknown types + next if $skip_interface{$name}; + next unless ($type eq 'all' || $type eq $intf->type()); + if ($intf->vrid()){ + push @match, $name; # add all vrrp interfaces + } elsif ($vif_name) { + next unless $intf->vif(); + push @match, $intf->vif() + if ($vif_name eq $intf->physicalDevice()); + } else { + push @match, $name + unless $intf->vif() + and $type ne 'all'; } - print join(' ', @match), "\n"; + } + print join(' ', @match), "\n"; } # Determine current values for autoneg, speed, duplex sub get_ethtool { - my $dev = shift; - - open(my $ethtool, '-|', "$ETHTOOL $dev 2>&1") - or die "ethtool failed: $!\n"; - - # ethtool produces: - # - # Settings for eth1: - # Supported ports: [ TP ] - # ... - # Speed: 1000Mb/s - # Duplex: Full - # ... - # Auto-negotiation: on - my ($rate, $duplex); - my $autoneg = 0; - while (<$ethtool>) { - chomp; - return if (/^Cannot get device settings/); - - if (/^\s+Speed: (\d+)Mb/) { - $rate = $1; - } elsif (/^\s+Duplex:\s(.*)$/) { - $duplex = lc $1; - } elsif (/^\s+Auto-negotiation: on/) { - $autoneg = 1; - } + my $dev = shift; + + open(my $ethtool, '-|', "$ETHTOOL $dev 2>&1") + or die "ethtool failed: $!\n"; + + # ethtool produces: + # + # Settings for eth1: + # Supported ports: [ TP ] + # ... + # Speed: 1000Mb/s + # Duplex: Full + # ... + # Auto-negotiation: on + my ($rate, $duplex) = (1000, "full"); + my $autoneg = 0; + while (<$ethtool>) { + chomp; + return if (/^Cannot get device settings/); + + if (/^\s+Speed: (\d+)Mb/) { + $rate = $1; + } elsif (/^\s+Duplex:\s(.*)$/) { + $duplex = lc $1; + } elsif (/^\s+Auto-negotiation: on/) { + $autoneg = 1; } - close $ethtool; - return ($autoneg, $rate, $duplex); + } + close $ethtool; + + $duplex = "full" if $duplex =~ /unknown.*/; + + return ($autoneg, $rate, $duplex); } sub set_speed_duplex { - my ($intf, $nspeed, $nduplex) = @_; - die "Missing --dev argument\n" unless $intf; - + my ($intf, $nspeed, $nduplex) = @_; + die "Missing --dev argument\n" unless $intf; + + ## if driver virtio, speed and duplex are unknown per default coming fromthe driver itself + ## if that's the case we always run ethtool and set the values + + open(my $ethtool, '-|', "$ETHTOOL -i $dev 2>&1") + or die "ethtool failed: $!\n"; + my $drv = 0; + while (<$ethtool>) + { + chomp; + return if (/^Cannot get device driver settings/); + $drv = 1 if (/^driver:.*/); + last; + } + + if ($drv != 1) + { # read old values to avoid meaningless speed changes my ($autoneg, $ospeed, $oduplex) = get_ethtool($intf); if (defined($autoneg) && $autoneg == 1) { - # Device is already in autonegotiation mode - return if ($nspeed eq 'auto'); + # Device is already in autonegotiation mode + return if ($nspeed eq 'auto'); } elsif (defined($ospeed) && defined($oduplex)) { - # Device has explicit speed/duplex but they already match - return if (($nspeed eq $ospeed) && ($nduplex eq $oduplex)); + # Device has explicit speed/duplex but they already match + return if (($nspeed eq $ospeed) && ($nduplex eq $oduplex)); } + } - my $cmd = "$ETHTOOL -s $intf"; - if ($nspeed eq 'auto') { - $cmd .= " autoneg on"; - } else { - $cmd .= " speed $nspeed duplex $nduplex autoneg off"; - } + my $cmd = "$ETHTOOL -s $intf"; + if ($nspeed eq 'auto') { + $cmd .= " autoneg on"; + } else { + $cmd .= " speed $nspeed duplex $nduplex autoneg off"; + } - exec $cmd; - die "exec of $ETHTOOL failed: $!"; + exec $cmd; + die "exec of $ETHTOOL failed: $!"; } # Check if speed and duplex value is supported by device sub is_supported_speed { - my ($dev, $speed, $duplex) = @_; - - my $wanted = sprintf("%dbase%s/%s", $speed,($speed == 2500) ? 'X' : 'T', ucfirst($duplex)); - - open(my $ethtool, '-|', "$ETHTOOL $dev 2>/dev/null") - or die "ethtool failed: $!\n"; - - # ethtool output: - # - # Settings for eth1: - # Supported ports: [ TP ] - # Supported link modes: 10baseT/Half 10baseT/Full - # 100baseT/Half 100baseT/Full - # 1000baseT/Half 1000baseT/Full - # Supports auto-negotiation: Yes - my $mode; - while (<$ethtool>) { - chomp; - if ($mode) { - last unless /^\t /; - } else { - next unless /^\tSupported link modes: /; - $mode = 1; - } - - return 1 if /$wanted/; + my ($dev, $speed, $duplex) = @_; + + open(my $if_drv, '-|', "$ETHTOOL -i $dev 2>/dev/null") + or die "ethtool -i failed: $!\n"; + + ### check if virtualized NIC + return 1 if <$if_drv> =~ /virtio_net/; + + my $wanted = sprintf("%dbase%s/%s", $speed,($speed == 2500) ? 'X' : 'T', ucfirst($duplex)); + + open(my $ethtool, '-|', "$ETHTOOL $dev 2>/dev/null") + or die "ethtool failed: $!\n"; + + # ethtool output: + # + # Settings for eth1: + # Supported ports: [ TP ] + # Supported link modes: 10baseT/Half 10baseT/Full + # 100baseT/Half 100baseT/Full + # 1000baseT/Half 1000baseT/Full + # Supports auto-negotiation: Yes + my $mode; + while (<$ethtool>) { + chomp; + if ($mode) { + last unless /^\t /; + } else { + next unless /^\tSupported link modes: /; + $mode = 1; } - close $ethtool; - return; + return 1 if /$wanted/; + } + + close $ethtool; + + return; } # Validate speed and duplex settings prior to commit sub check_speed_duplex { - my ($dev, $speed, $duplex) = @_; + my ($dev, $speed, $duplex) = @_; - # most basic and default case - exit 0 if ($speed eq 'auto' && $duplex eq 'auto'); + # most basic and default case + exit 0 if ($speed eq 'auto' && $duplex eq 'auto'); - die "If speed is hardcoded, duplex must also be hardcoded\n" - if ($duplex eq 'auto'); + die "If speed is hardcoded, duplex must also be hardcoded\n" + if ($duplex eq 'auto'); - die "If duplex is hardcoded, speed must also be hardcoded\n" - if ($speed eq 'auto'); + die "If duplex is hardcoded, speed must also be hardcoded\n" + if ($speed eq 'auto'); - die "Speed $speed, duplex $duplex not supported on $dev\n" - unless is_supported_speed($dev, $speed, $duplex); + die "Speed $speed, duplex $duplex not supported on $dev\n" + unless is_supported_speed($dev, $speed, $duplex); - exit 0; + exit 0; } # Produce list of valid speed values for device sub allowed_speed { - my ($dev) = @_; - - open(my $ethtool, '-|', "$ETHTOOL $dev 2>/dev/null") - or die "ethtool failed: $!\n"; - - my %speeds; - my $first = 1; - while (<$ethtool>) { - chomp; - - if ($first) { - next unless s/\tSupported link modes:\s//; - $first = 0; - } else { - last unless /^\t /; - } - - foreach my $val (split / /) { - $speeds{$1} = 1 if $val =~ /(\d+)base/; - } - } + my ($dev) = @_; - close $ethtool; - print 'auto ', join(' ', sort keys %speeds), "\n"; -} + open(my $ethtool, '-|', "$ETHTOOL $dev 2>/dev/null") + or die "ethtool failed: $!\n"; -sub get_offload_option { - my ($dev, $option) = @_; - my $val; - my $ethtool_option; + my %speeds; + my $first = 1; + while (<$ethtool>) { + chomp; - if ($option ne 'scatter-gather') { - $ethtool_option = "$option-offload"; + if ($first) { + next unless s/\tSupported link modes:\s//; + $first = 0; } else { - $ethtool_option = $option; + last unless /^\t /; } - open(my $ethtool, '-|', "$ETHTOOL -k $dev 2>&1") or die "ethtool failed: $!\n"; - while (<$ethtool>) { - next if ($_ !~ m/$ethtool_option:/); - chomp; - $val = (split(/: /, $_))[1]; + foreach my $val (split / /) { + $speeds{$1} = 1 if $val =~ /(\d+)base/; } - close $ethtool; - return $val; + } + + close $ethtool; + print 'auto ', join(' ', sort keys %speeds), "\n"; +} + +sub get_offload_option { + my ($dev, $option) = @_; + my $val; + my $ethtool_option; + + if ($option ne 'scatter-gather') { + $ethtool_option = "$option-offload"; + } else { + $ethtool_option = $option; + } + + open(my $ethtool, '-|', "$ETHTOOL -k $dev 2>&1") or die "ethtool failed: $!\n"; + while (<$ethtool>) { + next if ($_ !~ m/$ethtool_option:/); + chomp; + $val = (split(/: /, $_))[1]; + } + close $ethtool; + return $val; } sub set_offload_option { - my ($intf, $option, $nvalue) = @_; - die "Missing --dev argument\n" unless $intf; - - my $ovalue = get_offload_option($intf, $option); - - my %ethtool_opts = ( - 'generic-receive' => 'gro', - 'generic-segmentation' => 'gso', - 'tcp-segmentation' => 'tso', - 'udp-fragmentation' => 'ufo', - 'scatter-gather' => 'sg', - ); - - if (defined($nvalue) && $nvalue ne $ovalue) { - my $cmd = "$ETHTOOL -K $intf $ethtool_opts{$option} $nvalue"; - - system($cmd); - if ($? >> 8) { - die "Offload option for $option is not supported on $intf\n"; - } + my ($intf, $option, $nvalue) = @_; + die "Missing --dev argument\n" unless $intf; + + my $ovalue = get_offload_option($intf, $option); + + my %ethtool_opts = ( + 'generic-receive' => 'gro', + 'generic-segmentation' => 'gso', + 'tcp-segmentation' => 'tso', + 'udp-fragmentation' => 'ufo', + 'scatter-gather' => 'sg', + ); + + if (defined($nvalue) && $nvalue ne $ovalue) { + my $cmd = "$ETHTOOL -K $intf $ethtool_opts{$option} $nvalue"; + + system($cmd); + if ($? >> 8) { + die "Offload option for $option is not supported on $intf\n"; } + } } diff --git a/sysconf/vyatta-sysctl.conf b/sysconf/vyatta-sysctl.conf index 038b9f83..54f57541 100644 --- a/sysconf/vyatta-sysctl.conf +++ b/sysconf/vyatta-sysctl.conf @@ -74,3 +74,6 @@ net.core.rmem_max=2097152 # Do not forget IPv6 addresses when a link goes down net.ipv6.conf.default.keep_addr_on_down=1 net.ipv6.conf.all.keep_addr_on_down=1 + +# Default value of 20 seems to interfere with larger OSPF and VRRP setups +net.ipv4.igmp_max_memberships = 512 diff --git a/templates/interfaces/bridge/node.def b/templates/interfaces/bridge/node.def index b6654f07..cda535d5 100644 --- a/templates/interfaces/bridge/node.def +++ b/templates/interfaces/bridge/node.def @@ -11,10 +11,8 @@ create: /sbin/brctl addbr $VAR(@) fi sudo ip link set $VAR(@) up -delete: if ! /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ - --no-interfaces-assigned \ - --bridge-interface="$VAR(@)"; then \ - exit 1 +delete: if ! ${vyos_conf_scripts_dir}/bridge_has_members.py $VAR(@); then + exit 1; fi sudo ip link set $VAR(@) down; sudo /sbin/brctl delbr $VAR(@); diff --git a/templates/interfaces/tunnel/node.tag/parameters/ip/bridge-group/bridge/node.def b/templates/interfaces/tunnel/node.tag/parameters/ip/bridge-group/bridge/node.def index 85666c41..84d2c983 100644 --- a/templates/interfaces/tunnel/node.tag/parameters/ip/bridge-group/bridge/node.def +++ b/templates/interfaces/tunnel/node.tag/parameters/ip/bridge-group/bridge/node.def @@ -13,4 +13,8 @@ create: echo interfaces tunnel $VAR(../../../../@) bridge-group bridge $VAR(@): tunnel encapsulation type must be gre-bridge exit 1 fi -delete: sudo brctl delif $VAR(@) $VAR(../../../../@) +delete: if [ -d /sys/class/net/$VAR(@) ]; then + sudo brctl delif $VAR(@) $VAR(../../../../@) + else + exit 0 + fi diff --git a/templates/system/login/user/node.def b/templates/system/login/user/node.def index 451cc078..5f83fe54 100644 --- a/templates/system/login/user/node.def +++ b/templates/system/login/user/node.def @@ -3,6 +3,7 @@ type: txt help: User account information syntax:expression: exec "/opt/vyatta/sbin/vyatta_check_username.pl $VAR(@)" +syntax:expression: exec "${vyos_libexec_dir}/validate-value.py --regex \'^[a-zA-Z0-9\-_]{1,100}\' --value \'$VAR(@)\'"; "illegal characters in username or longer than 100 chars" commit:expression: $VAR(@) == "" || $VAR(authentication/plaintext-password) != "" || |