diff --git a/iscsi-client/delete_conns.cgi b/iscsi-client/delete_conns.cgi
index 7d27a867c..b9836e314 100755
--- a/iscsi-client/delete_conns.cgi
+++ b/iscsi-client/delete_conns.cgi
@@ -52,10 +52,12 @@ if (!$in{'confirm'}) {
print &ui_confirmation_form(
"delete_conns.cgi",
@delconns == 1 && $delconns[0]->{'device'} ?
- &text('dconns_rusure2', $delconns[0]->{'ip'},
- $delconns[0]->{'device'}) :
+ &text('dconns_rusure2',
+ "".$delconns[0]->{'ip'}."",
+ "".$delconns[0]->{'device'}."") :
@delconns == 1 ?
- &text('dconns_rusure1', $delconns[0]->{'ip'}) :
+ &text('dconns_rusure1',
+ "".$delconns[0]->{'ip'}."") :
&text('dconns_rusure', scalar(@delconns)),
[ map { [ "d", $_ ] } @d ],
[ [ "confirm", $text{'dconns_confirm'} ] ],
@@ -78,7 +80,7 @@ else {
'target' => $delconns[0]->{'target'} });
}
else {
- &webmin_log("delete", "connection", scalar(@delconns));
+ &webmin_log("delete", "connections", scalar(@delconns));
}
&redirect("list_conns.cgi");
}
diff --git a/iscsi-client/delete_ifaces.cgi b/iscsi-client/delete_ifaces.cgi
new file mode 100755
index 000000000..2a8d3c83c
--- /dev/null
+++ b/iscsi-client/delete_ifaces.cgi
@@ -0,0 +1,52 @@
+#!/usr/local/bin/perl
+# Remove one or more interfaces
+
+use strict;
+use warnings;
+require './iscsi-client-lib.pl';
+our (%text, %in);
+&ReadParse();
+&error_setup($text{'difaces_err'});
+
+# Get the interfaces
+my $ifaces = &list_iscsi_ifaces();
+ref($ifaces) || &error(&text('ifaces_elist', $ifaces));
+my @d = split(/\0/, $in{'d'});
+my @delifaces;
+foreach my $d (@d) {
+ my ($iface) = grep { $_->{'name'} eq $d } @$ifaces;
+ push(@delifaces, $iface) if ($iface);
+ }
+@delifaces || &error($text{'difaces_enone'});
+
+if (!$in{'confirm'}) {
+ &ui_print_header(undef, $text{'difaces_title'}, "");
+
+ # Ask the user if he is sure
+ print &ui_confirmation_form(
+ "delete_ifaces.cgi",
+ @delifaces == 1 ?
+ &text('difaces_rusure1',
+ "".$delifaces[0]->{'name'}."") :
+ &text('difaces_rusure', scalar(@delifaces)),
+ [ map { [ "d", $_ ] } @d ],
+ [ [ "confirm", $text{'difaces_confirm'} ] ]);
+
+ &ui_print_footer("list_ifaces.cgi", $text{'ifaces_return'});
+ }
+else {
+ # Delete each one
+ foreach my $iface (@delifaces) {
+ my $err = &delete_iscsi_iface($iface);
+ &error(&text('difaces_edelete', $iface->{'name'}, $err))
+ if ($err);
+ }
+
+ if (@delifaces == 1) {
+ &webmin_log("delete", "iface", $delifaces[0]->{'name'});
+ }
+ else {
+ &webmin_log("delete", "ifaces", scalar(@delifaces));
+ }
+ &redirect("list_ifaces.cgi");
+ }
diff --git a/iscsi-client/iscsi-client-lib.pl b/iscsi-client/iscsi-client-lib.pl
index d59a8a83d..64f253471 100644
--- a/iscsi-client/iscsi-client-lib.pl
+++ b/iscsi-client/iscsi-client-lib.pl
@@ -288,6 +288,7 @@ my ($iface, $target);
foreach my $l (@lines) {
if ($l =~ /^Iface:\s+(\S+)/) {
$iface = { 'name' => $1,
+ 'builtin' => ($1 eq "default" || $1 eq "iser"),
'targets' => [ ] };
push(@rv, $iface);
}
@@ -301,7 +302,60 @@ foreach my $l (@lines) {
$target->{'port'} = $2;
}
}
+# Fetch more info for each interface
+foreach my $iface (@rv) {
+ &clean_language();
+ my $out = &backquote_command(
+ "$config{'iscsiadm'} -m iface -I $iface->{'name'} 2>/dev/null");
+ &reset_environment();
+ foreach my $il (split(/\r?\n/, $out)) {
+ if ($il !~ /^#/ && $il =~ /^(iface.\S+)\s*=\s*(\S+)/) {
+ $iface->{$1} = $2 eq "" ? undef : $2;
+ }
+ }
+ }
return \@rv;
}
+# create_iscsi_interface(&iface)
+# Create a new interface from the given hash
+sub create_iscsi_interface
+{
+my ($iface) = @_;
+
+# Create the initial interface
+my $cmd = "$config{'iscsiadm'} -m iface -o create".
+ " -I ".quotemeta($iface->{'name'});
+&clean_language();
+my $out = &backquote_command("$cmd 2>&1");
+&reset_environment();
+return $out if ($?);
+
+# Apply various params
+foreach my $k (grep { /^iface\./ } keys %$iface) {
+ my $cmd = "$config{'iscsiadm'} -m iface -o update".
+ " -I ".quotemeta($iface->{'name'}).
+ " -n ".quotemeta($k)." -v ".quotemeta($iface->{$k});
+ &clean_language();
+ my $out = &backquote_command("$cmd 2>&1");
+ &reset_environment();
+ return "Failed to set $k : $out" if ($?);
+ }
+
+return undef;
+}
+
+# delete_iscsi_iface(&iface)
+# Delete one iSCSI interface
+sub delete_iscsi_iface
+{
+my ($iface) = @_;
+my $cmd = "$config{'iscsiadm'} -m iface -o delete".
+ " -I ".quotemeta($iface->{'name'});
+&clean_language();
+my $out = &backquote_command("$cmd 2>&1");
+&reset_environment();
+return $? ? $out : undef;
+}
+
1;
diff --git a/iscsi-client/lang/en b/iscsi-client/lang/en
index 920e94b9f..676a1f46f 100644
--- a/iscsi-client/lang/en
+++ b/iscsi-client/lang/en
@@ -69,6 +69,7 @@ iscsi_equeue=Missing or non-numeric maximum commands queued per device
ifaces_title=iSCSI Interfaces
ifaces_elist=Failed to list interfaces : $1
ifaces_name=Interface name
+ifaces_transport=Transport
ifaces_uses=Used by
ifaces_none=No iSCSI interfaces are currently active.
ifaces_return=interfaces list
@@ -76,6 +77,18 @@ ifaces_header=Add iSCSI interface
ifaces_delete=Remove Selected Interfaces
ifaces_on=Target $1 on $2
ifaces_nouses=No connections
+ifaces_ipaddress=Source IP address
+ifaces_hwaddress=MAC address
+ifaces_ifacename=Source interface
+ifaces_ipaddressdef=Automatic
+
+difaces_err=Failed to remove interfaces
+difaces_enone=None selected
+difaces_edelete=Removal of interface $1 failed : $2
+difaces_title=Remove iSCSI Interfaces
+difaces_rusure=Are you sure you want to remove the $1 selected interfaces?
+difaces_rusure1=Are you sure you want to remove the interface $1?
+difaces_confirm=Remove Interfaces
conns_title=iSCSI Connections
conns_elist=Failed to list connections : $1
@@ -152,3 +165,6 @@ log_delete_connection=Removed connection to $1 for $2
log_delete_connections=Removed $1 connections
log_atboot=Enabled iSCSI client at boot time
log_delboot=Disabled iSCSI client at boot time
+log_add_iface=Added interface $1
+log_delete_iface=Removed interface $1
+log_delete_ifaces=Removed $1 interfaces
diff --git a/iscsi-client/list_ifaces.cgi b/iscsi-client/list_ifaces.cgi
index 0c75f80b9..b8af821b2 100755
--- a/iscsi-client/list_ifaces.cgi
+++ b/iscsi-client/list_ifaces.cgi
@@ -15,14 +15,16 @@ if (@$ifaces) {
my @tds = ( "width=5" );
print &ui_form_start("delete_ifaces.cgi");
print &ui_columns_start(
- [ "", $text{'ifaces_name'}, $text{'ifaces_uses'} ],
+ [ "", $text{'ifaces_name'}, $text{'ifaces_transport'},
+ $text{'ifaces_uses'} ],
100, 0, \@tds);
foreach my $c (@$ifaces) {
my $uses = join(" | ", map { &text('ifaces_on', $_->{'target'}, $_->{'ip'}) } @{$c->{'targets'}});
print &ui_checked_columns_row([
$c->{'name'},
+ uc($c->{'iface.transport_name'}),
$uses || "$text{'ifaces_nouses'}",
- ], \@tds, "d", $c->{'name'});
+ ], \@tds, "d", $c->{'name'}, 0, $c->{'builtin'});
}
print &ui_columns_end();
print &ui_form_end([ [ undef, $text{'ifaces_delete'} ] ]);
@@ -39,7 +41,35 @@ print &ui_table_start($text{'ifaces_header'}, undef, 2);
print &ui_table_row($text{'ifaces_name'},
&ui_textbox("name", undef, 40));
-# XXX??
+# Transport type
+print &ui_table_row($text{'ifaces_transport'},
+ &ui_select("transport", "tcp",
+ [ [ "tcp", "TCP" ],
+ [ "iser", "ISER" ],
+ [ "cxgb3i", "Chelsio CXGB3I" ],
+ [ "bnx2i", "Broadcom BNX2I" ],
+ [ "be2iscsi", "ServerEngines BE2ISCSI" ] ]));
+
+# Source IP address
+print &ui_table_row($text{'ifaces_ipaddress'},
+ &ui_opt_textbox("ipaddress", undef, 20, $text{'ifaces_ipaddressdef'}));
+
+# MAC address
+print &ui_table_row($text{'ifaces_hwaddress'},
+ &ui_opt_textbox("hwaddress", undef, 30, $text{'ifaces_ipaddressdef'}));
+
+# Source interface
+my @active;
+if (&foreign_check("net")) {
+ &foreign_require("net");
+ @active = grep { $_->{'name'} ne 'lo' } &net::active_interfaces();
+ }
+if (@active) {
+ print &ui_table_row($text{'ifaces_ifacename'},
+ &ui_select("ifacename", undef,
+ [ map { $_->{'fullname'} }
+ grep { $_->{'virtual'} eq '' } @active ]));
+ }
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'create'} ] ]);
diff --git a/iscsi-client/log_parser.pl b/iscsi-client/log_parser.pl
index 506e23011..9c82f73ad 100755
--- a/iscsi-client/log_parser.pl
+++ b/iscsi-client/log_parser.pl
@@ -15,6 +15,12 @@ if ($type eq "connection") {
elsif ($type eq "connections") {
return &text('log_'.$action.'_'.$type, $object);
}
+elsif ($type eq "iface") {
+ return &text('log_'.$action.'_'.$type, &html_escape($object));
+ }
+elsif ($type eq "ifaces") {
+ return &text('log_'.$action.'_'.$type, $object);
+ }
else {
return $text{'log_'.$action};
}