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;
}
$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;
}
elsif ($cfg->{'bootp'} == 1) {
$method = 'bootp';
}
-else {
+elsif ($cfg->{'address'}) {
$method = 'static';
push(@options, ['address', $cfg->{'address'}]);
push(@options, ['netmask', $cfg->{'netmask'}]);
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', '']); }
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;
# 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'}, "");
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);
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);
}
$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'} ]);
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) {
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) {
# 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),
$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'} ],
}
# 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'}))) {
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
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
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
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
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>
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" );
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()) {
# 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);
$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'};
$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;
}
$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);
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;
if (defined($oldb->{'virtual'}));
$b->{'code'} = $oldb->{'code'};
$b->{'fullname'} = $oldb->{'fullname'};
+ $b->{'bridge'} = $oldb->{'bridge'};
}
elsif (defined($in{'virtual'})) {
# creating a virtual interface
$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;
}
}
+ # 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'});