mirror of
https://github.com/webmin/webmin.git
synced 2026-05-04 22:30:33 +01:00
Start of work on bridge support
This commit is contained in:
@@ -37,6 +37,9 @@ foreach $iface (@ifaces) {
|
||||
else {
|
||||
$cfg->{'name'} = $cfg->{'fullname'};
|
||||
}
|
||||
if ($cfg->{'fullname'} =~ /^br(\d+)$/) {
|
||||
$cfg->{'bridge'} = 1;
|
||||
}
|
||||
if ($gconfig{'os_version'} >= 3 || scalar(@autos)) {
|
||||
$cfg->{'up'} = &indexof($name, @autos) >= 0;
|
||||
}
|
||||
@@ -77,6 +80,13 @@ foreach $iface (@ifaces) {
|
||||
$cfg->{'ether_type'} = $v[0];
|
||||
$cfg->{'ether'} = $v[1];
|
||||
}
|
||||
elsif ($param eq 'bridge_ports') {
|
||||
$cfg->{'bridgeto'} = $value;
|
||||
}
|
||||
elsif ($param eq 'pre-up' &&
|
||||
$value =~ /brctl\s+addif\s+br\d+\s+(\S+)/) {
|
||||
$cfg->{'bridgeto'} = $1;
|
||||
}
|
||||
else {
|
||||
$cfg->{$param} = $value;
|
||||
}
|
||||
@@ -147,7 +157,7 @@ if ($cfg->{'dhcp'} == 1) {
|
||||
elsif ($cfg->{'bootp'} == 1) {
|
||||
$method = 'bootp';
|
||||
}
|
||||
else {
|
||||
elsif ($cfg->{'address'}) {
|
||||
$method = 'static';
|
||||
push(@options, ['address', $cfg->{'address'}]);
|
||||
push(@options, ['netmask', $cfg->{'netmask'}]);
|
||||
@@ -164,6 +174,9 @@ else {
|
||||
push(@options, ['network', $network]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$method = 'manual';
|
||||
}
|
||||
my @autos = get_auto_defs();
|
||||
my $amode = $gconfig{'os_version'} > 3 || scalar(@autos);
|
||||
if (!$cfg->{'up'} && !$amode) { push(@options, ['noauto', '']); }
|
||||
@@ -1023,5 +1036,18 @@ local ($iface) = @_;
|
||||
return !$iface || $iface->{'virtual'} eq '';
|
||||
}
|
||||
|
||||
# Returns 1, as boot-time interfaces on Debian can exist without an IP (such as
|
||||
# for bridging)
|
||||
sub supports_no_address
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Bridge interfaces can be created on debian
|
||||
sub supports_bridges
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
@@ -16,6 +16,16 @@ elsif ($in{'new'} && $in{'vlan'}) {
|
||||
# New VLAN
|
||||
&ui_print_header(undef, $text{'vlan_create'}, "");
|
||||
}
|
||||
elsif ($in{'new'} && $in{'bridge'}) {
|
||||
# New Bridge
|
||||
&ui_print_header(undef, $text{'bridge_create'}, "");
|
||||
$bmax = -1;
|
||||
foreach $b (@boot) {
|
||||
if ($b->{'fullname'} =~ /^br(\d+)$/) {
|
||||
$bmax = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($in{'new'}) {
|
||||
# New real or virtual interface
|
||||
&ui_print_header(undef, $text{'bifc_create'}, "");
|
||||
@@ -47,6 +57,7 @@ print &ui_hidden("new", $in{'new'});
|
||||
print &ui_hidden("idx", $in{'idx'});
|
||||
print &ui_hidden("vlan", $in{'vlan'});
|
||||
print &ui_hidden("bond", $in{'bond'});
|
||||
print &ui_hidden("bridge", $in{'bridge'});
|
||||
print &ui_table_start($in{'virtual'} || $b && $b->{'virtual'} ne "" ?
|
||||
$text{'bifc_desc2'} : $text{'bifc_desc1'},
|
||||
"width=100%", 4);
|
||||
@@ -69,6 +80,9 @@ elsif ($in{'new'}) {
|
||||
if ($in{'vlan'} == 1) {
|
||||
$namefield = "auto".&ui_hidden("name", "auto");
|
||||
}
|
||||
elsif ($in{'bridge'}) {
|
||||
$namefield = "br".&ui_textbox("name", ($bmax+1), 3);
|
||||
}
|
||||
else {
|
||||
$namefield = &ui_textbox("name", undef, 6);
|
||||
}
|
||||
@@ -94,6 +108,14 @@ print &ui_table_row($text{'ifcs_act'}, $upfield);
|
||||
$virtual = (!$b && $in{'virtual'}) || ($b && $b->{'virtual'} ne "");
|
||||
$dhcp = &can_edit("dhcp") && !$virtual;
|
||||
$bootp = &can_edit("bootp") && !$virtual;
|
||||
if (defined(&supports_no_address) && &supports_no_address()) {
|
||||
# Having no address is allowed
|
||||
$canno = 1;
|
||||
}
|
||||
elsif ($b && !$b->{'address'} && !$b->{'dhcp'} && !$b->{'bootp'}) {
|
||||
# Has no address
|
||||
$canno = 1;
|
||||
}
|
||||
@opts = ( );
|
||||
if ($dhcp) {
|
||||
push(@opts, [ "dhcp", $text{'ifcs_dhcp'} ]);
|
||||
@@ -101,6 +123,8 @@ if ($dhcp) {
|
||||
if ($bootp) {
|
||||
push(@opts, [ "bootp", $text{'ifcs_bootp'} ]);
|
||||
}
|
||||
if ($canno) {
|
||||
}
|
||||
@grid = ( $text{'ifcs_ip'},
|
||||
&ui_textbox("address", $b ? $b->{'address'} : "", 15) );
|
||||
if ($in{'virtual'} && $in{'new'} && $virtual_netmask) {
|
||||
@@ -129,6 +153,9 @@ elsif ($b && $b->{'broadcast'}) {
|
||||
push(@grid, $text{'ifcs_broad'}, "<tt>$b->{'broadcast'}</tt>");
|
||||
}
|
||||
push(@opts, [ "address", $text{'ifcs_static2'}, &ui_grid_table(\@grid, 2) ]);
|
||||
if ($canno) {
|
||||
push(@opts, [ "none", $text{'ifcs_noaddress'} ]);
|
||||
}
|
||||
|
||||
# Show the IP field
|
||||
if (@opts > 1) {
|
||||
@@ -147,7 +174,7 @@ if (&supports_address6($b)) {
|
||||
# Multiple IPs allowed
|
||||
$table6 = &ui_columns_start([ $text{'ifcs_address6'},
|
||||
$text{'ifcs_netmask6'} ], 50);
|
||||
for($i=0; $i<=@{$b->{'address6'}}; $i++) {
|
||||
for($i=0; $i<=($b ? scalar(@{$b->{'address6'}}) : 0); $i++) {
|
||||
$table6 .= &ui_columns_row([
|
||||
&ui_textbox("address6_$i",
|
||||
$b->{'address6'}->[$i], 40),
|
||||
@@ -157,6 +184,7 @@ if (&supports_address6($b)) {
|
||||
$table6 .= &ui_columns_end();
|
||||
print &ui_table_row($text{'ifcs_mode6'},
|
||||
&ui_radio_table("mode6",
|
||||
!$b ? "none" :
|
||||
$b->{'auto6'} ? "auto" :
|
||||
@{$b->{'address6'}} ? "address" : "none",
|
||||
[ [ "none", $text{'ifcs_none6'} ],
|
||||
@@ -238,7 +266,7 @@ if(($in{'vlan'}) or (&iface_type($b->{'name'}) =~ /^(.*) (VLAN)$/)) {
|
||||
}
|
||||
|
||||
# Hardware address, if non-virtual
|
||||
if (($in{'new'} && $in{'virtual'} eq "") ||
|
||||
if (($in{'new'} && $in{'virtual'} eq "" && !$in{'bridge'}) ||
|
||||
(!$in{'new'} && $b->{'virtual'} eq "" &&
|
||||
defined(&boot_iface_hardware) &&
|
||||
&boot_iface_hardware($b->{'name'}))) {
|
||||
@@ -247,6 +275,13 @@ if (($in{'new'} && $in{'virtual'} eq "") ||
|
||||
print &ui_table_row($text{'aifc_hard'}, $hardfield);
|
||||
}
|
||||
|
||||
# Real interface for bridge
|
||||
if ($in{'bridge'} || $b && $b->{'bridge'}) {
|
||||
@ethboot = grep { $_->{'fullname'} =~ /^eth(\d+)$/ } @boot;
|
||||
print &ui_table_row($text{'bifc_bridgeto'},
|
||||
&ui_select("bridgeto", $b->{'bridgeto'}, \@ethboot));
|
||||
}
|
||||
|
||||
print &ui_table_end();
|
||||
|
||||
# Generate and show buttons at end of the form
|
||||
|
||||
11
net/lang/en
11
net/lang/en
@@ -24,6 +24,7 @@ ifcs_up=Up
|
||||
ifcs_down=Down
|
||||
ifcs_add=Add a new interface.
|
||||
ifcs_radd=Add a new address range.
|
||||
ifcs_badd=Add a new bridge.
|
||||
ifcs_boot=Activated at Boot
|
||||
ifcs_act=Activate
|
||||
ifcs_bootp=From BOOTP
|
||||
@@ -42,6 +43,7 @@ ifcs_ecannot_this=You are not allowed to edit this network interface
|
||||
ifcs_range=Range $1
|
||||
ifcs_static2=Static configuration
|
||||
ifcs_static3=IPv6 enabled
|
||||
ifcs_noaddress=No address configured
|
||||
ifcs_mode=IPv4 address
|
||||
ifcs_mode6=IPv6 addresses
|
||||
ifcs_address6=IPv6 address
|
||||
@@ -100,9 +102,12 @@ bifc_err4=Failed to deactivate interface
|
||||
bifc_capply=Create and Apply
|
||||
bifc_eapply=You cannot activate an interface that uses DHCP or BOOTP
|
||||
bifc_edhcpmain=DHCP can only be enabled on the primary network interface
|
||||
bifc_bridgeto=Connect bridge to interface
|
||||
bifc_ebridgeto=An existing Ethernet interface must be selected for this bridge to use
|
||||
bifc_ebridgeto2=The selected interface for the bridge must not have any address assigned
|
||||
|
||||
bonding_add=Add a new bonding Interface.
|
||||
bonding_create=Create Bootup Bonding Interface
|
||||
bonding_create=Create Bonding Interface
|
||||
bonding_teamparts=Teaming Partner
|
||||
bonding_teammode=Teaming Mode
|
||||
bonding_miimon=Mii-Monitoring Interval
|
||||
@@ -112,7 +117,9 @@ bonding_downdelay=Downdelay
|
||||
vlan_add=Add Vlan Tagged Interface
|
||||
vlan_physical=Physical Device
|
||||
vlan_id=Vlan ID
|
||||
vlan_create=Create a VLAN tagged interface
|
||||
vlan_create=Create VLAN Interface
|
||||
|
||||
bridge_create=Create Bridge Interface
|
||||
|
||||
routes_title=Routing and Gateways
|
||||
routes_boot=Routing configuration activated at <i>boot time</i>
|
||||
|
||||
@@ -115,15 +115,21 @@ print &ui_form_start("delete_bifcs.cgi", "post");
|
||||
if ($allow_add) {
|
||||
push(@links, "<a href='edit_bifc.cgi?new=1'>$text{'ifcs_add'}</a>");
|
||||
if (defined(&supports_bonding) && &supports_bonding()) {
|
||||
push(@links, "<a href='edit_bifc.cgi?new=1&bond=1'>$text{'bonding_add'}</a>");
|
||||
push(@links, "<a href='edit_bifc.cgi?new=1&bond=1'>".
|
||||
"$text{'bonding_add'}</a>");
|
||||
}
|
||||
if (defined(&supports_vlans) && &supports_vlans()) {
|
||||
push(@links, "<a href='edit_bifc.cgi?new=1&vlan=1'>$text{'vlan_add'}</a>");
|
||||
push(@links, "<a href='edit_bifc.cgi?new=1&vlan=1'>".
|
||||
"$text{'vlan_add'}</a>");
|
||||
}
|
||||
}
|
||||
if ($allow_add && defined(&supports_ranges) && &supports_ranges()) {
|
||||
push(@links, "<a href='edit_range.cgi?new=1'>$text{'ifcs_radd'}</a>");
|
||||
}
|
||||
if ($allow_add && defined(&supports_bridges) && &supports_bridges()) {
|
||||
push(@links, "<a href='edit_bifcs.cgi?new=1&bridge=1'>".
|
||||
"$text{'ifcs_badd'}</a>");
|
||||
}
|
||||
print &ui_links_row(\@links);
|
||||
@tds = ( "width=5 valign=top", "width=20% valign=top", "width=20% valign=top",
|
||||
"width=20% valign=top", "width=20% valign=top" );
|
||||
@@ -202,7 +208,7 @@ foreach $a (@boot) {
|
||||
push(@cols, $a->{'bootp'} ? $text{'ifcs_bootp'} :
|
||||
$a->{'dhcp'} ? $text{'ifcs_dhcp'} :
|
||||
$a->{'address'} ? &html_escape($a->{'address'}) :
|
||||
$text{'ifcs_auto'});
|
||||
$text{'ifcs_noaddress'});
|
||||
push(@cols, $a->{'netmask'} ? &html_escape($a->{'netmask'})
|
||||
: $text{'ifcs_auto'});
|
||||
if (&supports_address6()) {
|
||||
|
||||
@@ -60,7 +60,8 @@ do 'linux-lib.pl';
|
||||
# Returns a list of interfaces brought up at boot time
|
||||
sub boot_interfaces
|
||||
{
|
||||
local(@rv, $f);
|
||||
local (@rv, $f);
|
||||
local %bridge_map;
|
||||
opendir(CONF, &translate_filename($net_scripts_dir));
|
||||
while($f = readdir(CONF)) {
|
||||
local (%conf, $b);
|
||||
@@ -89,7 +90,8 @@ while($f = readdir(CONF)) {
|
||||
$b->{'virtual'} = $2;
|
||||
}
|
||||
else { $b->{'name'} = $b->{'fullname'}; }
|
||||
$b->{'up'} = defined($conf{'ONPARENT'}) && $b->{'virtual'} ne '' ?
|
||||
$b->{'up'} = defined($conf{'ONPARENT'}) &&
|
||||
$b->{'virtual'} ne '' ?
|
||||
($conf{'ONPARENT'} eq 'yes') :
|
||||
($conf{'ONBOOT'} eq 'yes');
|
||||
$b->{'address'} = $conf{'IPADDR'};
|
||||
@@ -122,10 +124,19 @@ while($f = readdir(CONF)) {
|
||||
$b->{'desc'} = $conf{'NAME'};
|
||||
$b->{'index'} = scalar(@rv);
|
||||
$b->{'file'} = "$net_scripts_dir/$f";
|
||||
if ($conf{'BRIDGE'}) {
|
||||
$bridge_map{$conf{'BRIDGE'}} = $b->{'fullname};
|
||||
}
|
||||
push(@rv, $b);
|
||||
}
|
||||
}
|
||||
closedir(CONF);
|
||||
foreach my $b (@rv) {
|
||||
if ($b->{'fullname'} =~ /^br\d+$/) {
|
||||
$b->{'bridge'} = 1;
|
||||
$b->{'bridgeto'} = $bridge_map{$b->{'fullname'}};
|
||||
}
|
||||
}
|
||||
return @rv;
|
||||
}
|
||||
|
||||
@@ -192,6 +203,9 @@ else {
|
||||
$conf{'IPV6ADDR'} = shift(@ip6s);
|
||||
$conf{'IPV6ADDR_SECONDARIES'} = join(" ", @ip6s);
|
||||
}
|
||||
if ($_[0]->{'fullname'} =~ /^br(\d+)$/) {
|
||||
$conf{'TYPE'} = 'Bridge';
|
||||
}
|
||||
}
|
||||
$conf{'NAME'} = $_[0]->{'desc'};
|
||||
&write_env_file("$net_scripts_dir/ifcfg-$name", \%conf);
|
||||
@@ -868,5 +882,18 @@ local ($iface) = @_;
|
||||
return !$iface || $iface->{'virtual'} eq '';
|
||||
}
|
||||
|
||||
# Returns 1, as boot-time interfaces on Redhat can exist without an IP (such as
|
||||
# for bridging)
|
||||
sub supports_no_address
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Bridge interfaces can be created on redhat
|
||||
sub supports_bridges
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ else {
|
||||
if (defined($oldb->{'virtual'}));
|
||||
$b->{'code'} = $oldb->{'code'};
|
||||
$b->{'fullname'} = $oldb->{'fullname'};
|
||||
$b->{'bridge'} = $oldb->{'bridge'};
|
||||
}
|
||||
elsif (defined($in{'virtual'})) {
|
||||
# creating a virtual interface
|
||||
@@ -78,37 +79,40 @@ else {
|
||||
$b->{'name'} = $1;
|
||||
$b->{'virtual'} = $3;
|
||||
$b->{'fullname'} = $b->{'name'}.":".$b->{'virtual'};
|
||||
&can_create_iface() || &error($text{'ifcs_ecannot'});
|
||||
&can_iface($b) || &error($text{'ifcs_ecannot'});
|
||||
}
|
||||
elsif ($in{'bridge'}) {
|
||||
# Creating a bridge interface
|
||||
$in{'name'} =~ /^\d+$/ || &error($text{'bifc_ebridge'});
|
||||
$b->{'name'} = $b->{'fullname'} = "br".$in{'name'};
|
||||
}
|
||||
elsif ($in{'name'} =~/^[a-z]+\d*(\.\d+)?$/) {
|
||||
# creating a real interface
|
||||
foreach $eb (@boot) {
|
||||
if ($eb->{'fullname'} eq $in{'name'}) {
|
||||
&error(&text('bifc_edup', $in{'name'}));
|
||||
}
|
||||
}
|
||||
$b->{'name'} = $in{'name'};
|
||||
$b->{'fullname'} = $in{'name'};
|
||||
&can_create_iface() || &error($text{'ifcs_ecannot'});
|
||||
&can_iface($b) || &error($text{'ifcs_ecannot'});
|
||||
$b->{'bridge'} = 1;
|
||||
}
|
||||
elsif ($in{'name'} eq 'auto') {
|
||||
# creating a vlan interface
|
||||
foreach $eb (@boot) {
|
||||
if ($eb->{'fullname'} eq $in{'name'}) {
|
||||
&error(&text('bifc_edup', $in{'name'}));
|
||||
}
|
||||
}
|
||||
$b->{'name'} = $in{'name'};
|
||||
$b->{'fullname'} = $in{'name'};
|
||||
&can_create_iface() || &error($text{'ifcs_ecannot'});
|
||||
&can_iface($b) || &error($text{'ifcs_ecannot'});
|
||||
}
|
||||
else {
|
||||
&error($text{'bifc_ename'});
|
||||
}
|
||||
|
||||
if ($in{'new'}) {
|
||||
# Check permissions
|
||||
&can_create_iface() || &error($text{'ifcs_ecannot'});
|
||||
&can_iface($b) || &error($text{'ifcs_ecannot'});
|
||||
|
||||
# Check for clash
|
||||
foreach $eb (@boot) {
|
||||
if ($eb->{'fullname'} eq $b->{'fullname'}) {
|
||||
&error(&text('bifc_edup', $in{'name'}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Check for address clash
|
||||
$allow_clash = defined(&allow_interface_clash) ?
|
||||
&allow_interface_clash($b, 1) : 1;
|
||||
@@ -273,6 +277,17 @@ else {
|
||||
}
|
||||
}
|
||||
|
||||
# Save bridge settings
|
||||
if ($b->{'bridge'}) {
|
||||
$in{'bridgeto'} =~ /^eth\d+$/ ||
|
||||
&error($text{'bifc_ebridgeto'});
|
||||
($bt) = grep { $_->{'fullname'} eq $in{'bridgeto'} } @boot;
|
||||
$bt || &error($text{'bifc_ebridgeto'});
|
||||
($bt->{'address'} || $bt->{'dhcp'} || $bt->{'bootp'}) &&
|
||||
&error($text{'bifc_ebridgeto2'});
|
||||
$b->{'bridgeto'} = $in{'bridgeto'};
|
||||
}
|
||||
|
||||
# Save the interface with its final name
|
||||
$b->{'fullname'} = $b->{'name'}.
|
||||
( $b->{'virtual'} eq '' ? '' : ':'.$b->{'virtual'});
|
||||
|
||||
Reference in New Issue
Block a user