ACC SHELL
/**
* File: include/network/services/routing.ycp
* Package: Network configuration
* Summary: Routing configuration dialogs
* Authors: Michal Svec <msvec@suse.cz>
*
* $Id: routing.ycp 62060 2010-05-24 15:06:54Z mzugec $
*
* Routing configuration dialogs
*/
{
textdomain "network";
import "IP";
import "Label";
import "Netmask";
import "Popup";
import "Routing";
import "Wizard";
import "Lan";
import "CWM";
import "CWMTab";
import "NetworkService";
include "network/lan/help.ycp";
include "network/routines.ycp";
/**
* Route edit dialog
* @param id id of the edited route
* @param entry edited entry
* @param devs available devices
* @return route or nil, if canceled
*/
term RoutingEditDialog(integer id, term entry, list devs) {
// ScreenName("routing-edit");
UI::OpenDialog(`opt(`decorated),`VBox(
`HSpacing(1),
`VBox(
`HBox(
`InputField(`id(`destination), `opt(`hstretch), _("&Destination"), entry[1]:""),
`InputField(`id(`genmask), `opt(`hstretch), _("Ge&nmask"), entry[3]:"")
),
`HBox(
`InputField(`id(`gateway), `opt(`hstretch), _("&Gateway"), entry[2]:""),
`ComboBox(`id(`device), `opt(`editable, `hstretch), _("De&vice"), devs)
),
/* ComboBox label */
`InputField(`id(`options), `opt(`hstretch), Label::Options (), entry[5]:"")
),
`HSpacing(1),
`HBox(
`PushButton(`id(`ok), `opt(`default), Label::OKButton()),
`PushButton(`id(`cancel), Label::CancelButton())
)
));
//Allow declaring route without iface (for gateway) #93996
//if empty, use '-' which stands for any
if(entry[4]:"" != "")
UI::ChangeWidget(`id(`device), `Value, entry[4]:"");
else {
UI::ChangeWidget(`id(`device), `Items, devs);
}
UI::ChangeWidget(`id(`destination), `ValidChars, IP::ValidChars + "default" + "/-");
UI::ChangeWidget(`id(`gateway), `ValidChars, IP::ValidChars + "-");
UI::ChangeWidget(`id(`genmask), `ValidChars, Netmask::ValidChars + "-");
if(entry == `empty())
UI::SetFocus(`id(`destination));
else
UI::SetFocus(`id(`gateway));
any ret = nil;
term route = nil;
while(true) {
route = nil;
ret = UI::UserInput();
if(ret != `ok) break;
route = `item(`id(id));
string val = (string) UI::QueryWidget(`id(`destination), `Value);
integer slash = search (val, "/");
string noprefix = slash == nil? val: substring (val, 0, slash);
if(val != "default" && !IP::Check(noprefix)) {
/* Popup::Error text */
Popup::Error(_("Destination is invalid."));
UI::SetFocus(`id(`destination));
continue;
}
route = add(route, val);
val = (string) UI::QueryWidget(`id(`gateway), `Value);
if(val != "-" && !IP::Check(val)) {
/* Popup::Error text */
Popup::Error(_("Gateway IP address is invalid."));
UI::SetFocus(`id(`gateway));
continue;
}
route = add(route, val);
val = (string) UI::QueryWidget(`id(`genmask), `Value);
if(val != "-" && val != "0.0.0.0" && !Netmask::Check(val)) {
/* Popup::Error text */
Popup::Error(_("Subnetmask is invalid."));
UI::SetFocus(`id(`genmask));
continue;
}
route = add(route, val);
val = (string) UI::QueryWidget(`id(`device), `Value);
route = add(route, val);
val = (string) UI::QueryWidget(`id(`options), `Value);
route = add(route, val);
break;
}
UI::CloseDialog();
if(ret != `ok) return nil;
y2debug("route=%1", route);
return route;
}
list<term> r_items = [];
string defgw = "";
string defgwdev = "";
string defgw6 = "";
string defgwdev6 = "";
void initRouting (string key) ``{
integer max = 0;
// integer items = 0;
list<term> table_items_orig = [];
boolean forward = Routing::Forward;
list<map> route_conf = Routing::Routes;
//reset, so that UI really reflect current state
//maplist below will supply correct data, if there are some
defgw = "";
defgwdev = "-";
defgw6 = "";
defgwdev6 = "-";
r_items = [];
/* make ui items from the routes list */
term item = nil;
maplist(map r, route_conf, {
if(r["destination"]:"" == "default" && !issubstring(r["extrapara"]:"", "metric")) {
if (IP::Check4(r["gateway"]:"")){
defgw = r["gateway"]:"";
defgwdev = r["device"]:"";
} else {
defgw6 = r["gateway"]:"";
defgwdev6 = r["device"]:"";
}
}
else {
item = `item(`id(size(r_items)),
r["destination"]:"",
r["gateway"]:"",
r["netmask"]:"",
r["device"]:"",
r["extrapara"]:"");
r_items = add(r_items, item);
}
});
table_items_orig = (list<term>) eval(r_items);
y2debug("table_items=%1", r_items);
UI::ChangeWidget(`gw, `Value, defgw );
UI::ChangeWidget(`gw6, `Value, defgw6 );
UI::ChangeWidget(`id(`gw), `ValidChars, IP::ValidChars);
UI::ChangeWidget(`id(`table), `Items, r_items);
UI::ChangeWidget(`id(`forward), `Value, forward);
UI::SetFocus(`id(`gw));
// #178538 - disable routing dialog when NetworkManager is used
// but instead of default route (#299448) - NM reads it
boolean enabled = !(boolean)NetworkService::IsManaged();
UI::ChangeWidget(`id(`table), `Enabled, enabled);
UI::ChangeWidget(`id(`forward), `Enabled, enabled);
disableItemsIfNM([ `gw, `table, `add, `edit, `delete ], false);
if (!Lan::ipv6){
UI::ChangeWidget(`id(`gw6), `Enabled, false);
UI::ChangeWidget(`id(`gw6dev), `Enabled, false);
}
list devs = Routing::GetDevices();
devs= add(devs,"-");
UI::ChangeWidget(`gw4dev, `Items, devs);
UI::ChangeWidget(`gw4dev, `Value, defgwdev );
UI::ChangeWidget(`gw6dev, `Items, devs);
UI::ChangeWidget(`gw6dev, `Value, defgwdev6);
}
symbol handleRouting( string key, map event ) {
boolean enabled = !(boolean)NetworkService::IsManaged();
list devs = Routing::GetDevices();
devs= add(devs,"-");
integer cur = (integer) UI::QueryWidget(`id(`table), `CurrentItem);
term item=nil;
if (event["EventReason"]:"" == "Activated" || event["EventReason"]:"" == "ValueChanged")
{
switch (event["ID"]:`nil){
case `add:
item = RoutingEditDialog(size(r_items), `empty(), devs);
if(item != nil)
{
r_items = add(r_items, item);
UI::ChangeWidget(`id(`table), `Items, r_items);
}
break;
case `delete:
r_items = filter(term e, r_items, {
return cur != e[0, 0]:nil;
});
UI::ChangeWidget(`id(`table), `Items, r_items);
break;
case `edit:
list<term> cur_item = filter(term e, r_items, {
return cur == e[0, 0]:nil;
});
item = cur_item[0]:nil;
string dev = item[4]:"";
if (dev != "" && !contains(devs, dev))
devs = add(devs, dev);
devs = sort(devs);
item = RoutingEditDialog(cur, item, devs);
if(item != nil)
{
r_items = maplist(term e, r_items, {
if(cur == e[0, 0]:-1)
return item;
return e;
});
UI::ChangeWidget(`id(`table), `Items, r_items);
UI::ChangeWidget(`id(`table), `CurrentItem, cur);
}
break;
}
}
UI::ChangeWidget(`id(`add), `Enabled, enabled);
UI::ChangeWidget(`id(`edit), `Enabled, enabled && (size(r_items) > 0));
UI::ChangeWidget(`id(`delete), `Enabled, enabled && (size(r_items) > 0));
return nil;
}
boolean validateRouting (string key, map event){
string gw = (string) UI::QueryWidget(`id(`gw), `Value);
if(gw != "" && !IP::Check(gw)) {
Popup::Error(_("The default gateway is invalid."));
UI::SetFocus(`id(`gw));
return false;
} else return true;
}
void storeRouting (string key, map event) ``{
list<map> route_conf = maplist(term e, r_items, {
return $[
"destination" : e[1]:"",
"gateway" : e[2]:"",
"netmask" : e[3]:"",
"device" : e[4]:"",
"extrapara" : e[5]:"",
];
});
defgw = (string) UI::QueryWidget(`id(`gw), `Value);
defgwdev = (string)UI::QueryWidget(`id(`gw4dev), `Value);
defgw6 = (string) UI::QueryWidget(`id(`gw6), `Value);
defgwdev6 = (string)UI::QueryWidget(`id(`gw6dev), `Value);
if(defgw != "")
route_conf = add(route_conf, $[
"destination" : "default",
"gateway" : defgw,
"netmask" : "-",
"device" : defgwdev
]);
if(defgw6 != "")
route_conf = add(route_conf, $[
"destination" : "default",
"gateway" : defgw6,
"netmask" : "-",
"device" : defgwdev6
]);
Routing::Routes = route_conf;
Routing::Forward = (boolean) UI::QueryWidget(`id(`forward), `Value);
}
map<string, map<string,any> > wd_routing = $[
"ROUTING" : $[
"widget" : `custom,
"custom_widget" : `HBox(
`HSpacing(5),
`VBox(
`VStretch(),
/* ComboBox label */
`HBox(
`InputField(`id(`gw), `opt(`hstretch), _("Default IPv4 &Gateway") ),
`ComboBox(`id(`gw4dev), `opt(`editable), _("Device"), [])
),
`HBox(
`InputField(`id(`gw6), `opt(`hstretch), _("Default IPv6 &Gateway") ),
`ComboBox(`id(`gw6dev), `opt(`editable), _("Device"), [])
),
`VSpacing(1),
/* Frame label */
`Frame(_("Routing Table"), `VBox(
/* CheckBox label */
`Table(`id(`table), `opt(`notify), `header(
/* Table header 1/4 */
_("Destination"),
/* Table header 2/4 */
_("Gateway"),
/* Table header 3/4 */
_("Genmask"),
/* Table header 4/4 */
_("Device"),
/* Table header 5/4 */
// FIXME
deletechars (Label::Options (), "&")
), []),
/* PushButton label */
`HBox(`PushButton(`id(`add), _("Ad&d")),
/* PushButton label */
`PushButton(`id(`edit), _("&Edit")),
/* PushButton label */
`PushButton(`id(`delete), _("De&lete"))))),
`VSpacing(1),
/* CheckBox label */
`Left(`CheckBox(`id(`forward), _("Enable &IP Forwarding"))),
`VStretch()
),
`HSpacing(5)
),
"init" : initRouting,
"handle" : handleRouting,
"validate_type" : `function,
"validate_function" : validateRouting,
"store" : storeRouting,
"help" : help["routing"]:""
]
];
map route_td = $[
"route" : $[
"header" : _("Routing"),
"contents" : `VBox (
"ROUTING"
),
"widget_names" : ["ROUTING"]
],
];
/**
* Main routing dialog
* @return dialog result
*/
define any RoutingMainDialog() {
string caption = _("Routing Configuration");
map functions = $[
"init" : initRouting,
"store" : storeRouting,
`abort : ReallyAbort,
];
term contents = `VBox("ROUTING");
Wizard::HideBackButton();
symbol ret = CWM::ShowAndRun (
$[
"widget_descr" : wd_routing,
"contents" : contents,
"caption" : caption,
"back_button" : Label::BackButton(),
"next_button" : Label::NextButton(),
"fallback_functions" : functions,
]);
return ret;
}
/**
* Check if internal data differ from the dialog values
* @param defgw current default gw widget contents
* @return true if differ
*/
define boolean RoutingModified(string defgw) {
boolean forward = (boolean) UI::QueryWidget(`id(`forward), `Value);
string defg = (string) UI::QueryWidget(`id(`gw), `Value);
return forward != Routing::Forward || defg != defgw;
}
/* EOF */
}
ACC SHELL 2018