3 # Create, save or delete a boot-time interface
5 require './net-lib.pl';
7 @boot = &boot_interfaces();
9 if ($in{'delete'} || $in{'unapply'}) {
11 &error_setup($text{'bifc_err1'});
12 $b = $boot[$in{'idx'}];
13 &can_iface($b) || &error($text{'ifcs_ecannot_this'});
16 # Shut down this interface active (if active)
17 &error_setup($text{'bifc_err4'});
18 @active = &active_interfaces();
19 ($act) = grep { $_->{'fullname'} eq $b->{'fullname'} } @active;
21 if (defined(&unapply_interface)) {
22 $err = &unapply_interface($act);
23 $err && &error("<pre>$err</pre>");
26 &deactivate_interface($act);
31 &delete_interface($b);
32 &webmin_log("delete", "bifc", $b->{'fullname'}, $b);
35 # Save or create interface
36 &error_setup($text{'bifc_err2'});
38 # Modifying an interface
39 $oldb = $boot[$in{'idx'}];
40 &can_iface($oldb) || &error($text{'ifcs_ecannot_this'});
41 $b->{'name'} = $oldb->{'name'};
42 $b->{'file'} = $oldb->{'file'};
43 $b->{'gateway'} = $oldb->{'gateway'};
44 $b->{'virtual'} = $oldb->{'virtual'}
45 if (defined($oldb->{'virtual'}));
46 $b->{'code'} = $oldb->{'code'};
47 $b->{'fullname'} = $oldb->{'fullname'};
48 $b->{'bridge'} = $oldb->{'bridge'};
50 elsif (defined($in{'virtual'})) {
51 # creating a virtual interface
52 $in{'virtual'} =~ /^\d+$/ ||
53 &error($text{'bifc_evirt'});
54 $in{'virtual'} >= $min_virtual_number ||
55 &error(&text('aifc_evirtmin', $min_virtual_number));
57 if ($eb->{'name'} eq $in{'name'} &&
58 $eb->{'virtual'} eq $in{'virtual'}) {
59 &error(&text('bifc_evirtdup',
60 "$in{'name'}:$in{'virtual'}"));
63 $b->{'name'} = $in{'name'};
64 $b->{'virtual'} = $in{'virtual'};
65 $b->{'fullname'} = $b->{'name'}.":".$b->{'virtual'};
66 &can_create_iface() || &error($text{'ifcs_ecannot'});
67 &can_iface($b) || &error($text{'ifcs_ecannot'});
69 elsif ($in{'name'} =~ /^([a-z]+\d*(\.\d+)?):(\d+)$/) {
70 # also creating a virtual interface
72 if ($eb->{'name'} eq $1 &&
73 $eb->{'virtual'} eq $3) {
74 &error(&text('bifc_evirtdup', $in{'name'}));
77 $3 >= $min_virtual_number ||
78 &error(&text('aifc_evirtmin', $min_virtual_number));
81 $b->{'fullname'} = $b->{'name'}.":".$b->{'virtual'};
83 elsif ($in{'bridge'}) {
84 # Creating a bridge interface
85 $in{'name'} =~ /^\d+$/ || &error($text{'bifc_ebridge'});
86 $b->{'name'} = $b->{'fullname'} = "br".$in{'name'};
89 elsif ($in{'name'} =~/^[a-z]+\d*(\.\d+)?$/) {
90 # creating a real interface
91 $b->{'name'} = $in{'name'};
92 $b->{'fullname'} = $in{'name'};
94 elsif ($in{'name'} eq 'auto') {
95 # creating a vlan interface
96 $b->{'name'} = $in{'name'};
97 $b->{'fullname'} = $in{'name'};
100 &error($text{'bifc_ename'});
105 &can_create_iface() || &error($text{'ifcs_ecannot'});
106 &can_iface($b) || &error($text{'ifcs_ecannot'});
109 foreach $eb (@boot) {
110 if ($eb->{'fullname'} eq $b->{'fullname'}) {
111 &error(&text('bifc_edup', $in{'name'}));
116 # Check for address clash
117 $allow_clash = defined(&allow_interface_clash) ?
118 &allow_interface_clash($b, 1) : 1;
119 if (!$allow_clash && $in{'mode'} eq 'address' &&
120 ($in{'new'} || $oldb->{'address'} ne $in{'address'})) {
121 ($clash) = grep { $_->{'address'} eq $in{'address'} &&
123 $clash && &error(&text('aifc_eclash', $clash->{'fullname'}));
126 # Validate and store inputs
127 if ($in{'mode'} eq 'dhcp' || $in{'mode'} eq 'bootp') {
128 $in{'activate'} && !defined(&apply_interface) &&
129 &error($text{'bifc_eapply'});
133 elsif ($in{'mode'} eq 'none') {
134 delete($b->{'address'});
137 &valid_boot_address($in{'address'}) ||
138 &error(&text('bifc_eip', $in{'address'}));
139 $b->{'address'} = $in{'address'};
142 # Set description if possible
143 if (defined($in{'desc'})) {
144 $b->{'desc'} = $in{'desc'};
147 if ($in{'mode'} eq 'none') {
149 delete($b->{'netmask'});
151 elsif ($virtual_netmask && $b->{'virtual'} ne "") {
152 # Always use this netmask for virtuals
153 $b->{'netmask'} = $virtual_netmask;
155 elsif (!$access{'netmask'}) {
156 # Use default netmask
157 $b->{'netmask'} = $in{'new'} ?
158 $config{'def_netmask'} || "255.255.255.0" :
161 elsif (&can_edit("netmask", $b) && $access{'netmask'}) {
162 $auto && !$in{'netmask'} ||
163 &check_netmask($in{'netmask'},$in{'address'}) ||
164 &error(&text('bifc_emask', $in{'netmask'}));
165 $b->{'netmask'} = $in{'netmask'};
168 if ($in{'mode'} eq 'none') {
169 # No broadcast needed
170 delete($b->{'broadcast'});
172 elsif (!$access{'broadcast'} || $in{'broadcast_def'}) {
174 $b->{'broadcast'} = $in{'new'} ?
175 &compute_broadcast($b->{'address'}, $b->{'netmask'}) :
176 $oldb->{'broadcast'};
178 elsif (&can_edit("broadcast", $b)) {
179 # Manually entered broadcast
180 ($auto && !$in{'broadcast'}) ||
181 &check_ipaddress($in{'broadcast'}) ||
182 &error(&text('bifc_ebroad', $in{'broadcast'}));
183 $b->{'broadcast'} = $in{'broadcast'};
186 if ($in{'mode'} eq 'none') {
190 elsif (!$access{'mtu'}) {
192 $b->{'mtu'} = $in{'new'} ? $config{'def_mtu'}
195 elsif (&can_edit("mtu", $b) && $access{'mtu'}) {
196 $auto && !$in{'mtu'} ||
198 $in{'mtu'} =~ /^\d+$/ ||
199 &error(&text('bifc_emtu', $in{'mtu'}));
200 $b->{'mtu'} = $in{'mtu_def'} ? undef : $in{'mtu'};
204 if (defined($in{'ether'}) && !$in{'ether_def'}) {
205 $in{'ether'} =~ /^[A-Fa-f0-9:]+$/ ||
206 &error(&text('aifc_ehard', $in{'ether'}));
207 $b->{'ether'} = $in{'ether'};
210 # Activate at boot flag
211 if ($in{'new'} && !$access{'up'} ||
212 &can_edit("up", $b) && $in{'up'} && $access{'up'}) {
215 elsif (!$access{'up'}) {
216 $b->{'up'} = $oldb->{'up'};
219 # Save IPv6 addresses
220 if (&supports_address6($b) && $in{'mode6'} eq 'auto') {
221 # Dynamic configuration
222 delete($b->{'address6'});
223 delete($b->{'netmask6'});
226 elsif (&supports_address6($b) && $in{'mode6'} eq 'address') {
231 foreach $eb (@boot) {
232 if ($eb->{'fullname'} ne $b->{'fullname'}) {
233 foreach $a6 (@{$eb->{'address6'}}) {
238 for($i=0; defined($in{'address6_'.$i}); $i++) {
239 next if ($in{'address6_'.$i} !~ /\S/);
240 &check_ip6address($in{'address6_'.$i}) ||
241 &error(&text('aifc_eaddress6', $i+1));
242 $c = $clash6{$in{'address6_'.$i}};
243 $c && &error(&text('aifc_eclash6', $i+1, $c->{'name'}));
244 push(@address6, $in{'address6_'.$i});
245 $in{'netmask6_'.$i} =~ /^\d+$/ &&
246 $in{'netmask6_'.$i} > 0 &&
247 $in{'netmask6_'.$i} <= 128 ||
248 &error(&text('aifc_enetmask6', $i+1));
249 push(@netmask6, $in{'netmask6_'.$i});
250 $clash6{$in{'address6_'.$i}} = $b;
252 @address6 || &error($text{'aifc_eaddresses6'});
253 delete($b->{'auto6'});
254 $b->{'address6'} = \@address6;
255 $b->{'netmask6'} = \@netmask6;
257 elsif (&supports_address6($b) && $in{'mode6'} eq 'none') {
259 delete($b->{'address6'});
260 delete($b->{'netmask6'});
261 delete($b->{'auto6'});
264 # Save bonding settings
267 if ($in{'partner'}) {
268 $b->{'partner'} = $in{'partner'};
270 if ($in{'bondmode'} ne ''){
271 $mode = $in{'bondmode'};
272 $b->{'mode'} = $mode;
274 if ($in{'miimon'} ne ''){
275 $b->{'miimon'} = $in{'miimon'};
277 if ($in{'updelay'} ne ''){
278 $b->{'updelay'} = $in{'updelay'};
280 if ($in{'downdelay'} ne ''){
281 $b->{'downdelay'} = $in{'downdelay'};
286 if ($in{'vlan'} == 1) {
288 if ($in{'physical'}) {
289 $b->{'physical'} = $in{'physical'};
292 $b->{'vlanid'} = $in{'vlanid'};
296 # Save bridge settings
297 if ($b->{'bridge'}) {
298 $in{'bridgeto'} =~ /^eth\d+$/ ||
299 &error($text{'bifc_ebridgeto'});
300 ($bt) = grep { $_->{'fullname'} eq $in{'bridgeto'} } @boot;
301 $bt || &error($text{'bifc_ebridgeto'});
302 ($bt->{'address'} || $bt->{'dhcp'} || $bt->{'bootp'}) &&
303 &error($text{'bifc_ebridgeto2'});
304 $b->{'bridgeto'} = $in{'bridgeto'};
307 # Save the interface with its final name
308 $b->{'fullname'} = $b->{'name'}.
309 ( $b->{'virtual'} eq '' ? '' : ':'.$b->{'virtual'});
312 if ($in{'activate'}) {
313 # Make this interface active (if possible)
314 &error_setup($text{'bifc_err3'});
316 $b->{'address'} = &to_ipaddress($b->{'address'});
317 if (defined(&apply_interface)) {
318 $err = &apply_interface($b);
319 $err && &error("<pre>$err</pre>");
323 if (($gconfig{'os_type'} eq 'debian-linux') &&
324 ($gconfig{'os_version'} >= 5)) {}
325 else {&load_module($b);}
327 &activate_interface($b);
330 &webmin_log($in{'new'} ? 'create' : 'modify',
331 "bifc", $b->{'fullname'}, $b);
333 &redirect("list_ifcs.cgi?mode=boot");