1 /*
2
3 Firewall Builder
4
5 Copyright (C) 2002 NetCitadel, LLC
6
7 Author: Vadim Kurland vadim@vk.crocodile.org
8
9 $Id$
10
11 This program is free software which we release under the GNU General Public
12 License. You may redistribute and/or modify this program under the terms
13 of that license as published by the Free Software Foundation; either
14 version 2 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 To get a copy of the GNU General Public License, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
24 */
25
26
27 #include "config.h"
28
29 #include "OSConfigurator_linux24.h"
30
31 #include "fwbuilder/InetAddr.h"
32
33 #include "fwbuilder/Firewall.h"
34 #include "fwbuilder/FWOptions.h"
35 #include "fwbuilder/Interface.h"
36 #include "fwbuilder/IPv4.h"
37 #include "fwbuilder/Network.h"
38 #include "fwbuilder/Address.h"
39 #include "fwbuilder/Resources.h"
40 #include "fwbuilder/MultiAddress.h"
41 #include "fwbuilder/FailoverClusterGroup.h"
42 #include "fwbuilder/XMLTools.h"
43
44 #include "Configlet.h"
45
46 #ifndef _WIN32
47 # include <unistd.h>
48 #endif
49
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <fcntl.h>
53 #include <ctype.h>
54
55 #include <algorithm>
56 #include <functional>
57 #include <iostream>
58
59 #include <assert.h>
60
61 #include <QString>
62 #include <QtDebug>
63 #include <QRegExp>
64 #include <QStringList>
65
66
67 using namespace libfwbuilder;
68 using namespace fwcompiler;
69 using namespace std;
70
myPlatformName()71 string OSConfigurator_linux24::myPlatformName() { return "Linux24"; }
72
OSConfigurator_linux24(FWObjectDatabase * _db,Firewall * fw,bool ipv6_policy)73 OSConfigurator_linux24::OSConfigurator_linux24(FWObjectDatabase *_db,
74 Firewall *fw,
75 bool ipv6_policy) :
76 OSConfigurator(_db, fw, ipv6_policy) , os_data(fw->getStr("host_OS"))
77 {
78 command_wrappers = new Configlet(fw, "linux24", "run_time_wrappers");
79
80 FWOptions* fwopt = fw->getOptionsObject();
81 string version = fw->getStr("version");
82 using_ipset = (XMLTools::version_compare(version, "1.4.1.1") >= 0 &&
83 fwopt->getBool("use_m_set"));
84 }
85
~OSConfigurator_linux24()86 OSConfigurator_linux24::~OSConfigurator_linux24()
87 {
88 delete command_wrappers;
89 }
90
91 /*
92 * this function generates acceptable shell variable name from
93 * interface name. Note that PolicyCompiler_ipt::getInterfaceVarName()
94 * and NATCompiler_ipt::getInterfaceVarName do the same thing and
95 * these functions should be identical.
96 *
97 * TODO: really need to have one function for this instead of three in
98 * three different classes.
99 */
getInterfaceVarName(FWObject * iface,bool v6)100 string OSConfigurator_linux24::getInterfaceVarName(FWObject *iface, bool v6)
101 {
102 ostringstream ostr;
103 string iname=iface->getName();
104 string::size_type p1;
105 while ( (p1=iname.find("."))!=string::npos)
106 iname=iname.replace(p1,1,"_");
107 while ( (p1=iname.find("-"))!=string::npos)
108 iname=iname.replace(p1,1,"_");
109 ostr << "i_" << iname;
110 if (v6) ostr << "_v6";
111 return ostr.str();
112 }
113
setConfigletMacroForOptionStr(const string & s,Configlet * c,const char * option_name)114 void OSConfigurator_linux24::setConfigletMacroForOptionStr(
115 const string &s, Configlet *c, const char *option_name)
116 {
117 // "" means no change, do not include the command in the script
118 if (!s.empty())
119 {
120 c->setVariable(QString("if_") + option_name, 1);
121 c->setVariable(option_name, s.c_str());
122 } else
123 {
124 c->setVariable(QString("if_") + option_name, 0);
125 c->setVariable(option_name, s.c_str());
126 }
127 }
128
setConfigletMacroForOptionInt(int val,Configlet * c,const char * option_name)129 void OSConfigurator_linux24::setConfigletMacroForOptionInt(
130 int val, Configlet *c, const char *option_name)
131 {
132 // -1 means no change, do not include the command in the script
133 if (val >= 0)
134 {
135 c->setVariable(QString("if_") + option_name, 1);
136 c->setVariable(option_name, val);
137 } else
138 {
139 c->setVariable(QString("if_") + option_name, 0);
140 c->setVariable(option_name, 0);
141 }
142 }
143
processFirewallOptions()144 void OSConfigurator_linux24::processFirewallOptions()
145 {
146 Configlet kernel_vars(fw, "linux24", "kernel_vars");
147 kernel_vars.removeComments();
148 kernel_vars.collapseEmptyStrings(true);
149
150 FWOptions* options = fw->getOptionsObject();
151
152 setConfigletMacroForOptionStr(options->getStr("linux24_ip_dynaddr"), &kernel_vars, "linux24_ip_dynaddr");
153 setConfigletMacroForOptionStr(options->getStr("linux24_rp_filter"), &kernel_vars, "linux24_rp_filter");
154 setConfigletMacroForOptionStr(options->getStr("linux24_accept_source_route"), &kernel_vars, "linux24_accept_source_route");
155 setConfigletMacroForOptionStr(options->getStr("linux24_accept_redirects"), &kernel_vars, "linux24_accept_redirects");
156 setConfigletMacroForOptionStr(options->getStr("linux24_log_martians"), &kernel_vars, "linux24_log_martians");
157 setConfigletMacroForOptionStr(options->getStr("linux24_icmp_echo_ignore_broadcasts"), &kernel_vars, "linux24_icmp_echo_ignore_broadcasts");
158 setConfigletMacroForOptionStr(options->getStr("linux24_icmp_echo_ignore_all"), &kernel_vars, "linux24_icmp_echo_ignore_all");
159 setConfigletMacroForOptionStr(options->getStr("linux24_icmp_ignore_bogus_error_responses"), &kernel_vars, "linux24_icmp_ignore_bogus_error_responses");
160 setConfigletMacroForOptionStr(options->getStr("linux24_tcp_window_scaling"), &kernel_vars, "linux24_tcp_window_scaling");
161 setConfigletMacroForOptionStr(options->getStr("linux24_tcp_sack"), &kernel_vars, "linux24_tcp_sack");
162 setConfigletMacroForOptionStr(options->getStr("linux24_tcp_fack"), &kernel_vars, "linux24_tcp_fack");
163 setConfigletMacroForOptionStr(options->getStr("linux24_tcp_syncookies"), &kernel_vars, "linux24_tcp_syncookies");
164 setConfigletMacroForOptionStr(options->getStr("linux24_tcp_ecn"), &kernel_vars, "linux24_tcp_ecn");
165 setConfigletMacroForOptionStr(options->getStr("linux24_tcp_timestamps"), &kernel_vars, "linux24_tcp_timestamps");
166
167 int opt = options->getInt("linux24_tcp_fin_timeout");
168 setConfigletMacroForOptionInt((opt==0)?-1:opt, &kernel_vars, "linux24_tcp_fin_timeout");
169 opt = options->getInt("linux24_tcp_keepalive_interval");
170 setConfigletMacroForOptionInt((opt==0)?-1:opt, &kernel_vars, "linux24_tcp_keepalive_interval");
171
172 Configlet conntrack_vars(fw, "linux24", "conntrack");
173 conntrack_vars.removeComments();
174 conntrack_vars.collapseEmptyStrings(true);
175
176 string version = fw->getStr("version");
177 bool version_ge_1_4 = XMLTools::version_compare(version, "1.4.0") >= 0;
178 conntrack_vars.setVariable("iptables_version_ge_1_4", version_ge_1_4);
179 conntrack_vars.setVariable("iptables_version_lt_1_4", !version_ge_1_4);
180
181 // if conntrack_max and conntrack_hashsize are equal to 0, we do
182 // not add commands from the configlet (so the kernel defaults are
183 // used). Options above assume -1 is the default. Need to pass -1
184 // instead of 0 for the conntrack vars
185 opt = options->getInt("linux24_conntrack_max");
186 setConfigletMacroForOptionInt(
187 (opt==0)?-1:opt,
188 &conntrack_vars, "conntrack_max");
189 opt = options->getInt("linux24_conntrack_hashsize");
190 setConfigletMacroForOptionInt(
191 (opt==0)?-1:opt,
192 &conntrack_vars, "conntrack_hashsize");
193
194 // This option uses three-state control and assumes empty string is the default
195 setConfigletMacroForOptionStr(
196 options->getStr("linux24_conntrack_tcp_be_liberal"),
197 &conntrack_vars, "conntrack_tcp_be_liberal");
198
199 output << kernel_vars.expand().toStdString();
200 output << endl;
201 output << conntrack_vars.expand().toStdString();
202 }
203
addVirtualAddressForNAT(const Network * nw)204 void OSConfigurator_linux24::addVirtualAddressForNAT(const Network *nw)
205 {
206 FWOptions* options=fw->getOptionsObject();
207 if (options->getBool("manage_virtual_addr"))
208 {
209 if (virtual_addresses.empty() ||
210 find(virtual_addresses.begin(),virtual_addresses.end(),
211 *(nw->getAddressPtr())) == virtual_addresses.end())
212 {
213 Interface *iface = findInterfaceFor( nw, fw );
214 if (iface!=NULL)
215 {
216 const InetAddr *addr = nw->getAddressPtr();
217 InetAddr first, last;
218 InetAddr a;
219
220 first = *addr;
221 last = *(nw->getBroadcastAddressPtr());
222
223 QStringList addresses;
224 for (a=first; a<last; a=a+1)
225 {
226 addresses.push_back(QString("%1/32").arg(a.toString().c_str()));
227 }
228
229 if (virtual_addresses_for_nat.count(iface->getName()) > 0)
230 addresses.push_front(virtual_addresses_for_nat[iface->getName()].c_str());
231
232 virtual_addresses_for_nat[iface->getName()] =
233 addresses.join(" ").toStdString();
234
235 virtual_addresses.push_back( *(nw->getAddressPtr()) );
236 registerVirtualAddressForNat();
237 } else
238 warning("Can not add virtual address " +
239 nw->getAddressPtr()->toString() +
240 " (object " + nw->getName() + ")" );
241 }
242 }
243 }
244
addVirtualAddressForNAT(const Address * addr)245 void OSConfigurator_linux24::addVirtualAddressForNAT(const Address *addr)
246 {
247 FWOptions* options=fw->getOptionsObject();
248 if ( options->getBool("manage_virtual_addr") )
249 {
250 const InetAddr *addr_addr = addr->getAddressPtr();
251
252 if (virtual_addresses.empty() ||
253 find(virtual_addresses.begin(),
254 virtual_addresses.end(), *addr_addr) == virtual_addresses.end())
255 {
256 FWObject *vaddr = findAddressFor(addr, fw );
257 if (vaddr!=NULL)
258 {
259 Interface *iface = Interface::cast(vaddr->getParent());
260 assert(iface!=NULL);
261
262 QStringList addresses;
263 const InetAddr *vaddr_netm =
264 Address::cast(vaddr)->getNetmaskPtr();
265
266 addresses.push_back(QString("%1/%2").
267 arg(addr_addr->toString().c_str()).
268 arg(vaddr_netm->getLength()));
269
270 if (virtual_addresses_for_nat.count(iface->getName()) > 0)
271 addresses.push_front(virtual_addresses_for_nat[iface->getName()].c_str());
272
273 virtual_addresses_for_nat[iface->getName()] =
274 addresses.join(" ").toStdString();
275
276 virtual_addresses.push_back(*(addr_addr));
277 registerVirtualAddressForNat();
278 } else
279 warning("Can not add virtual address for object " + addr->getName());
280 }
281 return;
282 }
283 }
284
normalizeSetName(const string & txt)285 string OSConfigurator_linux24::normalizeSetName(const string &txt)
286 {
287 QString table_name = txt.c_str();
288 table_name.replace(QRegExp("[ +*!#|]"), "_");
289 return table_name.toStdString();
290 }
291
registerMultiAddressObject(MultiAddressRunTime * at)292 void OSConfigurator_linux24::registerMultiAddressObject(MultiAddressRunTime *at)
293 {
294 // std::map<std::string,std::string>
295 address_table_objects[normalizeSetName(at->getName())] = at->getSourceName();
296 }
297
prolog()298 int OSConfigurator_linux24::prolog()
299 {
300 return 0;
301 }
302
303 /**
304 * Print shell functions used by the script. If argument (boolean) is true,
305 * do not add comments.
306 */
printShellFunctions(bool have_ipv6)307 string OSConfigurator_linux24::printShellFunctions(bool have_ipv6)
308 {
309 QStringList output;
310 FWOptions* options = fw->getOptionsObject();
311
312 string version = fw->getStr("version");
313 // string host_os = fw->getStr("host_OS");
314 // string os_family = Resources::os_res[host_os]->
315 // getResourceStr("/FWBuilderResources/Target/family");
316
317 Configlet shell_functions(fw, "linux24", "shell_functions");
318 output.push_back(shell_functions.expand());
319
320 /* check if package iproute2 is installed, but do this only if
321 * we really need /usr/sbin/ip
322 */
323 Configlet configlet(fw, "linux24", "check_utilities");
324 configlet.removeComments();
325 configlet.collapseEmptyStrings(true);
326
327 configlet.setVariable("load_modules", options->getBool("load_modules"));
328
329 if (options->getBool("load_modules") ||
330 options->getBool("configure_vlan_interfaces") ||
331 options->getBool("configure_bonding_interfaces"))
332 {
333 configlet.setVariable("need_modprobe", true);
334 }
335
336 if (options->getBool("verify_interfaces") ||
337 options->getBool("manage_virtual_addr") ||
338 options->getBool("configure_interfaces") )
339 {
340 configlet.setVariable("need_vconfig",
341 options->getBool("configure_vlan_interfaces"));
342 configlet.setVariable("need_brctl",
343 options->getBool("configure_bridge_interfaces"));
344 configlet.setVariable("need_ifenslave",
345 options->getBool("configure_bonding_interfaces"));
346 }
347
348 configlet.setVariable("need_ipset", using_ipset);
349
350 configlet.setVariable("need_iptables_restore",
351 options->getBool("use_iptables_restore"));
352
353 configlet.setVariable("need_ip6tables_restore",
354 have_ipv6 && options->getBool("use_iptables_restore"));
355
356 output.push_back(configlet.expand());
357
358 /*
359 * Generate commands to reset all tables and chains and set
360 * default policy
361 */
362 Configlet reset_iptables(fw, "linux24", "reset_iptables");
363 if (XMLTools::version_compare(version, "1.4.20") >= 0)
364 reset_iptables.setVariable("opt_wait", "-w");
365 else
366 reset_iptables.setVariable("opt_wait", "");
367
368 output.push_back(reset_iptables.expand());
369
370 Configlet addr_conf(fw, "linux24", "update_addresses");
371 output.push_back(addr_conf.expand());
372
373 if (options->getBool("configure_vlan_interfaces"))
374 {
375 Configlet conf(fw, "linux24", "update_vlans");
376 output.push_back(conf.expand());
377 }
378
379 if (options->getBool("configure_bridge_interfaces"))
380 {
381 Configlet conf(fw, "linux24", "update_bridge");
382 output.push_back(conf.expand());
383 }
384
385 if (options->getBool("configure_bonding_interfaces"))
386 {
387 Configlet conf(fw, "linux24", "update_bonding");
388 output.push_back(conf.expand());
389 }
390
391 return output.join("\n").toStdString();
392 }
393
printRunTimeAddressTablesCode()394 string OSConfigurator_linux24::printRunTimeAddressTablesCode()
395 {
396 Configlet conf(fw, "linux24", "run_time_address_tables");
397 conf.setVariable("using_ipset", using_ipset);
398
399 ostringstream check_ostr;
400 ostringstream load_ostr;
401 map<string,string>::iterator i;
402 for (i=address_table_objects.begin(); i!=address_table_objects.end(); ++i)
403 {
404 string at_name = i->first;
405 string at_file = i->second;
406 // If the file name is empty, this run-time table is
407 // completely controlled by the user outside fwbuilder so we
408 // do not need to add commands to check if the file exits and
409 // load it
410 if (!at_file.empty())
411 {
412 check_ostr << "check_file \"" + at_name +
413 "\" \"" + at_file + "\"" << endl;
414 load_ostr << "reload_address_table \"" + at_name +
415 "\" \"" + at_file + "\"" << endl;
416 }
417 }
418
419 conf.setVariable("check_files_commands", check_ostr.str().c_str());
420 conf.setVariable("load_files_commands", load_ostr.str().c_str());
421
422 return conf.expand().toStdString();
423 }
424
getPathForATool(const std::string & os_variant,OSData::tools tool_name)425 string OSConfigurator_linux24::getPathForATool(const std::string &os_variant, OSData::tools tool_name)
426 {
427 FWOptions* options = fw->getOptionsObject();
428 string attr = os_data.getAttributeNameForTool(tool_name);
429
430 string s = options->getStr("linux24_" + attr);
431 if (!s.empty()) return s;
432
433 string host_os = fw->getStr("host_OS");
434 string r = "/FWBuilderResources/Target/tools/" + os_variant + "/" + attr;
435 if (Resources::os_res[host_os]->getResourceStr(r).empty())
436 r = "/FWBuilderResources/Target/tools/Unknown/" + attr;
437
438 return Resources::os_res[host_os]->getResourceStr(r);
439 }
440
printPathForAllTools(const string & os)441 string OSConfigurator_linux24::printPathForAllTools(const string &os)
442 {
443 ostringstream res;
444
445 list<int>::const_iterator i;
446 const list<int> &all_tools = os_data.getAllTools();
447 for (i=all_tools.begin(); i!=all_tools.end(); ++i)
448 res << os_data.getVariableName(OSData::tools(*i))
449 << "=\""
450 << getPathForATool(os, OSData::tools(*i))
451 << "\""
452 << endl;
453 return res.str();
454 }
455
generateCodeForProtocolHandlers()456 string OSConfigurator_linux24::generateCodeForProtocolHandlers()
457 {
458 FWOptions* options = fw->getOptionsObject();
459 bool nomod = Resources::os_res[fw->getStr("host_OS")]->
460 Resources::getResourceBool("/FWBuilderResources/Target/options/suppress_modules");
461
462 // string host_os = fw->getStr("host_OS");
463 // string os_family = Resources::os_res[host_os]->
464 // getResourceStr("/FWBuilderResources/Target/family");
465 Configlet load_modules(fw, "linux24", "load_modules");
466 load_modules.removeComments();
467
468 // See ticket #2
469 string modules_dir = Resources::os_res[fw->getStr("host_OS")]->
470 Resources::getResourceStr("/FWBuilderResources/Target/options/default/modules_dir");
471
472 /* there is no need to load modules on some platforms */
473 load_modules.setVariable("load_modules", options->getBool("load_modules") && !nomod);
474 load_modules.setVariable("modules_dir", modules_dir.c_str());
475 return load_modules.expand().toStdString();
476 }
477
addressTableWrapper(FWObject * rule,const QString & command,bool ipv6)478 QString OSConfigurator_linux24::addressTableWrapper(FWObject *rule,
479 const QString &command,
480 bool ipv6)
481 {
482 QString combined_command = command;
483 QRegExp address_table_re("\\$at_(\\S+)");
484 int pos = address_table_re.indexIn(command);
485 if (pos > -1)
486 {
487 QStringList command_lines = QString(command).split("\n", QString::SkipEmptyParts);
488 if (command_lines.size() > 1)
489 {
490 command_lines.push_front("{");
491 command_lines.push_back("}");
492 }
493 combined_command = command_lines.join("\n");
494
495 command_wrappers->clear();
496 command_wrappers->removeComments();
497 command_wrappers->collapseEmptyStrings(true);
498 command_wrappers->setVariable("ipv6", ipv6);
499
500 QString at_var = address_table_re.cap(1);
501 QString at_file = rule->getStr("address_table_file").c_str();
502
503 command_wrappers->setVariable("address_table_file", at_file);
504 command_wrappers->setVariable("address_table_var", at_var);
505 command_wrappers->setVariable("command", combined_command);
506 command_wrappers->setVariable("address_table", true);
507 command_wrappers->setVariable("wildcard_interface", false);
508 command_wrappers->setVariable("no_dyn_addr", false);
509 command_wrappers->setVariable("one_dyn_addr", false);
510 command_wrappers->setVariable("two_dyn_addr", false);
511
512 combined_command = command_wrappers->expand();
513 }
514 return combined_command;
515 }
516
printRunTimeWrappers(FWObject * rule,const string & command,bool ipv6)517 string OSConfigurator_linux24::printRunTimeWrappers(FWObject *rule,
518 const string &command,
519 bool ipv6)
520 {
521 /* if anywhere in command_line we used variable holding an address of
522 * dynamic interface (named $i_something) then we need to add this
523 * command with a check for the value of this variable. We execute
524 * iptables command only if the value is a non-empty string.
525 *
526 * bug #1851166: there could be two dynamic interfaces in the same
527 * rule.
528 */
529
530 bool wildcard_interface = false;
531 QString combined_command;
532
533 if (using_ipset)
534 combined_command = command.c_str();
535 else
536 combined_command = addressTableWrapper(rule, command.c_str(), ipv6);
537
538 command_wrappers->clear();
539 command_wrappers->removeComments();
540 command_wrappers->collapseEmptyStrings(true);
541 command_wrappers->setVariable("ipv6", ipv6);
542
543 command_wrappers->setVariable("address_table", false);
544
545 QRegExp intf_re("\\$i_([^ :]+)");
546
547 QStringList iface_names;
548 QStringList iface_vars;
549 int pos = -1;
550 while ((pos = intf_re.indexIn(combined_command, pos + 1)) > -1)
551 {
552 QString name = intf_re.cap(1);
553 int match_len = intf_re.matchedLength();
554 iface_names.push_back(name);
555 iface_vars.push_back("$i_" + name);
556 if (name.contains("*"))
557 {
558 wildcard_interface = true;
559 QString intf_family = name.section('*', 0, 0);
560 command_wrappers->setVariable("interface_family_name", intf_family);
561
562 // replace $i_ppp* with $addr. This must match shell code
563 // in the configlet run_time_wrappers
564 combined_command.replace(pos, match_len, "$addr");
565
566 break;
567 }
568 }
569
570 bool no_wrapper = !wildcard_interface && iface_names.size() == 0;
571
572 if (!no_wrapper)
573 {
574 QStringList command_lines =
575 QString(combined_command).split("\n", QString::SkipEmptyParts);
576 if (command_lines.size() > 1)
577 {
578 command_lines.push_front("{");
579 command_lines.push_back("}");
580 }
581 combined_command = command_lines.join("\n");
582 }
583
584 command_wrappers->setVariable("no_wrapper", no_wrapper);
585 command_wrappers->setVariable("wildcard_interface", wildcard_interface);
586 command_wrappers->setVariable("one_dyn_addr",
587 !wildcard_interface && iface_names.size() == 1);
588 command_wrappers->setVariable("two_dyn_addr",
589 !wildcard_interface && iface_names.size() > 1);
590
591 for (int idx=0; idx<iface_names.size(); ++idx)
592 {
593 QString intf_name = iface_names[idx];
594 //if (ipv6) intf_name += "_v6";
595 command_wrappers->setVariable(QString("intf_%1_var_name").arg(idx+1),
596 intf_name);
597 }
598
599 command_wrappers->setVariable("command", combined_command);
600
601 return command_wrappers->expand().toStdString() + "\n";
602 }
603
printIPForwardingCommands()604 string OSConfigurator_linux24::printIPForwardingCommands()
605 {
606 /* Turn on packet forwarding if we have to */
607 // string os_family = Resources::os_res[fw->getStr("host_OS")]->
608 // getResourceStr("/FWBuilderResources/Target/family");
609 FWOptions* options = fw->getOptionsObject();
610 Configlet ip_forwarding(fw, "linux24", "ip_forwarding");
611 ip_forwarding.removeComments();
612 ip_forwarding.collapseEmptyStrings(true);
613
614 string s = options->getStr("linux24_ip_forward");
615 ip_forwarding.setVariable("ipv4", !s.empty());
616 ip_forwarding.setVariable("ipv4_forw", (s=="1" || s=="On" || s=="on")?1:0);
617
618 s = options->getStr("linux24_ipv6_forward");
619 ip_forwarding.setVariable("ipv6", !s.empty());
620 ip_forwarding.setVariable("ipv6_forw", (s=="1" || s=="On" || s=="on")?1:0);
621
622 return ip_forwarding.expand().toStdString();
623 }
624
epilog()625 void OSConfigurator_linux24::epilog()
626 {
627 }
628
629
getGeneratedFiles() const630 map<string, string> OSConfigurator_linux24::getGeneratedFiles() const
631 {
632 map<string, string> files;
633 return files;
634 }
635