Add support for IPv6
This commit is contained in:
parent
4702710f7c
commit
18e7be6bf8
212
econnman-bin.in
212
econnman-bin.in
|
@ -56,10 +56,10 @@ except:
|
||||||
|
|
||||||
dbus_ml = DBusEcoreMainLoop()
|
dbus_ml = DBusEcoreMainLoop()
|
||||||
bus = dbus.SystemBus(mainloop=dbus_ml)
|
bus = dbus.SystemBus(mainloop=dbus_ml)
|
||||||
log = logging.getLogger("econnman")
|
log = logging.getLogger("econnman-bin")
|
||||||
log_handler = logging.StreamHandler()
|
log_handler = logging.StreamHandler()
|
||||||
log_formatter = logging.Formatter(
|
log_formatter = logging.Formatter(
|
||||||
"%(relativeCreated)d %(levelname)s %(name)s: %(message)s"
|
"%(created)d %(name)s [%(levelname)s]:: %(message)s (@lineno %(lineno)d)"
|
||||||
)
|
)
|
||||||
log_handler.setFormatter(log_formatter)
|
log_handler.setFormatter(log_formatter)
|
||||||
log.addHandler(log_handler)
|
log.addHandler(log_handler)
|
||||||
|
@ -347,6 +347,20 @@ class ObjectView(object):
|
||||||
sc.callback_changed_add(callback)
|
sc.callback_changed_add(callback)
|
||||||
return sc, items
|
return sc, items
|
||||||
|
|
||||||
|
def add_label_and_segment_control(self, box, options, callback, label):
|
||||||
|
lb = self.add_label(box, label)
|
||||||
|
|
||||||
|
sc = SegmentControl(box)
|
||||||
|
sc.size_hint_weight = EXPAND_HORIZ
|
||||||
|
sc.size_hint_align = FILL_BOTH
|
||||||
|
items = {}
|
||||||
|
for o in options:
|
||||||
|
items[o] = sc.item_add(None, o)
|
||||||
|
sc.show()
|
||||||
|
box.pack_end(sc)
|
||||||
|
sc.callback_changed_add(callback)
|
||||||
|
return lb, sc, items
|
||||||
|
|
||||||
def add_frame_and_box(self, box, label):
|
def add_frame_and_box(self, box, label):
|
||||||
fr = Frame(box)
|
fr = Frame(box)
|
||||||
fr.size_hint_weight = EXPAND_HORIZ
|
fr.size_hint_weight = EXPAND_HORIZ
|
||||||
|
@ -925,6 +939,28 @@ class ServiceView(ObjectView):
|
||||||
"""
|
"""
|
||||||
bus_interface = "net.connman.Service"
|
bus_interface = "net.connman.Service"
|
||||||
|
|
||||||
|
ipv4_fields = (#("Method", "ipv4_method"),
|
||||||
|
("Address", "ipv4_address"),
|
||||||
|
("Netmask", "ipv4_netmask"),
|
||||||
|
("Gateway", "ipv4_gateway"),
|
||||||
|
)
|
||||||
|
ipv6_fields = (#("Method", "ipv6_method"),
|
||||||
|
("Address", "ipv6_address"),
|
||||||
|
("Prefix Length", "ipv6_prefix_length"),
|
||||||
|
("Gateway", "ipv6_gateway"),
|
||||||
|
#("Privacy", "ipv6_privacy"),
|
||||||
|
)
|
||||||
|
proxy_fields = (("Method", "proxy_method"),
|
||||||
|
("URL", "proxy_url"),
|
||||||
|
("Servers", "proxy_servers"),
|
||||||
|
("Excludes", "proxy_excludes"),
|
||||||
|
)
|
||||||
|
vpn_fields = ( # named Provider in spec
|
||||||
|
("Host", "vpn_host"),
|
||||||
|
("Domain", "vpn_domain"),
|
||||||
|
("Name", "vpn_name"),
|
||||||
|
("Type", "vpn_type"),
|
||||||
|
)
|
||||||
eth_fields = (("Method", "eth_method"),
|
eth_fields = (("Method", "eth_method"),
|
||||||
("Interface", "eth_iface"),
|
("Interface", "eth_iface"),
|
||||||
("Address", "eth_addr"),
|
("Address", "eth_addr"),
|
||||||
|
@ -932,15 +968,6 @@ class ServiceView(ObjectView):
|
||||||
("Speed", "eth_speed"),
|
("Speed", "eth_speed"),
|
||||||
("Duplex", "eth_duplex"),
|
("Duplex", "eth_duplex"),
|
||||||
)
|
)
|
||||||
vpn_fields = (("Host", "vpn_host"),
|
|
||||||
("Domain", "vpn_domain"),
|
|
||||||
("Name", "vpn_name"),
|
|
||||||
("Type", "vpn_type"),
|
|
||||||
)
|
|
||||||
ipv4_fields = (("Address", "ipv4_address"),
|
|
||||||
("Netmask", "ipv4_netmask"),
|
|
||||||
("Gateway", "ipv4_gateway"),
|
|
||||||
)
|
|
||||||
|
|
||||||
top_widgets = (
|
top_widgets = (
|
||||||
"connect",
|
"connect",
|
||||||
|
@ -959,6 +986,7 @@ class ServiceView(ObjectView):
|
||||||
"domains_label",
|
"domains_label",
|
||||||
"domains_entry",
|
"domains_entry",
|
||||||
"ipv4_frame",
|
"ipv4_frame",
|
||||||
|
"ipv6_frame",
|
||||||
"proxy_frame",
|
"proxy_frame",
|
||||||
"ethernet_frame",
|
"ethernet_frame",
|
||||||
"vpn_frame",
|
"vpn_frame",
|
||||||
|
@ -1033,10 +1061,22 @@ class ServiceView(ObjectView):
|
||||||
en.callback_unfocused_add(self._on_ipv4_property_unfocused)
|
en.callback_unfocused_add(self._on_ipv4_property_unfocused)
|
||||||
setattr(self, attr, en)
|
setattr(self, attr, en)
|
||||||
|
|
||||||
# section: IPv6: similar to ipv4? refactor ipv4?
|
# section: IPv6
|
||||||
if properties.get("IPv6"):
|
self.ipv6_properties = {"IPv6": {}, "IPv6.Configuration": {}}
|
||||||
fr, bx = self.add_frame_and_box(self.box, "IPv6")
|
fr, bx = self.add_frame_and_box(self.box, "IPv6")
|
||||||
lb = self.add_label(bx, "TODO")
|
self.ipv6_frame = fr
|
||||||
|
self.ipv6_box = bx
|
||||||
|
options = ("Automatic", "Manual", "Off")
|
||||||
|
self.ipv6_method, self.ipv6_method_items = self.add_segment_control(
|
||||||
|
bx, options, self._on_ipv6_method)
|
||||||
|
for name, attr in self.ipv6_fields:
|
||||||
|
lb, en = self.add_label_and_entry(bx, name)
|
||||||
|
en.callback_activated_add(self._on_ipv6_property_changed)
|
||||||
|
en.callback_unfocused_add(self._on_ipv6_property_unfocused)
|
||||||
|
setattr(self, attr, en)
|
||||||
|
options = ("Disabled", "Enabled", "Prefered")
|
||||||
|
self.ipv6_privacy_lb, self.ipv6_privacy, self.ipv6_privacy_items = self.add_label_and_segment_control(
|
||||||
|
bx, options, self._on_ipv6_privacy, "Privacy")
|
||||||
|
|
||||||
# section: Proxy: custom contents for direct, auto and manual
|
# section: Proxy: custom contents for direct, auto and manual
|
||||||
# - direct: nothing
|
# - direct: nothing
|
||||||
|
@ -1186,6 +1226,11 @@ class ServiceView(ObjectView):
|
||||||
self.ipv4_address.disabled = value
|
self.ipv4_address.disabled = value
|
||||||
self.ipv4_netmask.disabled = value
|
self.ipv4_netmask.disabled = value
|
||||||
self.ipv4_gateway.disabled = value
|
self.ipv4_gateway.disabled = value
|
||||||
|
self.ipv6_method.disabled = value
|
||||||
|
self.ipv6_address.disabled = value
|
||||||
|
self.ipv6_prefix_length.disabled = value
|
||||||
|
self.ipv6_gateway.disabled = value
|
||||||
|
self.ipv6_privacy.disabled = value
|
||||||
self.proxy_method.disabled = value
|
self.proxy_method.disabled = value
|
||||||
elif name == "Favorite":
|
elif name == "Favorite":
|
||||||
value = bool(value)
|
value = bool(value)
|
||||||
|
@ -1250,6 +1295,47 @@ class ServiceView(ObjectView):
|
||||||
self.ipv4_method_items["Off"].selected = True
|
self.ipv4_method_items["Off"].selected = True
|
||||||
elif method:
|
elif method:
|
||||||
log.error("Unknown method: %s", method)
|
log.error("Unknown method: %s", method)
|
||||||
|
elif name in ("IPv6", "IPv6.Configuration"):
|
||||||
|
self.ipv6_properties[name] = value
|
||||||
|
used = self.ipv6_properties["IPv6"]
|
||||||
|
conf = self.ipv6_properties["IPv6.Configuration"]
|
||||||
|
|
||||||
|
def get_val(name):
|
||||||
|
v = used.get(name) or conf.get(name)
|
||||||
|
if not v:
|
||||||
|
return ""
|
||||||
|
return str(v)
|
||||||
|
self.ipv6_address.text = get_val("Address")
|
||||||
|
self.ipv6_prefix_length.text = get_val("PrefixLength")
|
||||||
|
self.ipv6_gateway.text = get_val("Gateway")
|
||||||
|
|
||||||
|
method = str(conf.get("Method", ""))
|
||||||
|
editable = (method == "manual") and (not self.immutable)
|
||||||
|
self.ipv6_address.editable = editable
|
||||||
|
self.ipv6_prefix_length.editable = editable
|
||||||
|
self.ipv6_gateway.editable = editable
|
||||||
|
# privacy has only meaning if Method is set to "auto"
|
||||||
|
editable = (method == "auto") and (not self.immutable)
|
||||||
|
self.ipv6_privacy.disabled = not editable
|
||||||
|
|
||||||
|
if method in ("auto", "fixed", "6to4"):
|
||||||
|
self.ipv6_method_items["Automatic"].selected = True
|
||||||
|
elif method == "manual":
|
||||||
|
self.ipv6_method_items["Manual"].selected = True
|
||||||
|
elif method == "off":
|
||||||
|
self.ipv6_method_items["Off"].selected = True
|
||||||
|
elif method:
|
||||||
|
log.error("Unknown method: %s", method)
|
||||||
|
|
||||||
|
privacy = str(conf.get("Privacy", ""))
|
||||||
|
if privacy == "disabled":
|
||||||
|
self.ipv6_privacy_items["Disabled"].selected = True
|
||||||
|
elif privacy == "enabled":
|
||||||
|
self.ipv6_privacy_items["Enabled"].selected = True
|
||||||
|
elif privacy == "prefered":
|
||||||
|
self.ipv6_privacy_items["Prefered"].selected = True
|
||||||
|
elif privacy:
|
||||||
|
log.error("Unknown privacy: %s", privacy)
|
||||||
|
|
||||||
elif name in ("Proxy", "Proxy.Configuration"):
|
elif name in ("Proxy", "Proxy.Configuration"):
|
||||||
self.proxy_properties[name] = value
|
self.proxy_properties[name] = value
|
||||||
|
@ -1437,6 +1523,102 @@ class ServiceView(ObjectView):
|
||||||
self.ipv4_netmask.text = get_val("Netmask")
|
self.ipv4_netmask.text = get_val("Netmask")
|
||||||
self.ipv4_gateway.text = get_val("Gateway")
|
self.ipv4_gateway.text = get_val("Gateway")
|
||||||
|
|
||||||
|
def _ipv6_apply(self):
|
||||||
|
value = self.ipv6_method.item_selected.text
|
||||||
|
if value == "Automatic":
|
||||||
|
method = "auto"
|
||||||
|
elif value == "Manual":
|
||||||
|
method = "manual"
|
||||||
|
elif value == "Off":
|
||||||
|
method = "off"
|
||||||
|
|
||||||
|
def make_variant(s):
|
||||||
|
return dbus.String(s, variant_level=1)
|
||||||
|
new = {"Method": make_variant(method)}
|
||||||
|
if method == "manual":
|
||||||
|
if self.ipv6_address.text:
|
||||||
|
new["Address"] = make_variant(self.ipv6_address.text)
|
||||||
|
if self.ipv6_prefix_length.text:
|
||||||
|
new["PrefixLength"] = make_variant(self.ipv6_prefix_length.text)
|
||||||
|
if self.ipv6_gateway.text:
|
||||||
|
new["Gateway"] = make_variant(self.ipv6_gateway.text)
|
||||||
|
value = self.ipv6_privacy.item_selected.text
|
||||||
|
if value:
|
||||||
|
new["Privacy"] = make_variant(value)
|
||||||
|
if len(new) == 1: # no properties yet
|
||||||
|
return
|
||||||
|
|
||||||
|
conf = self.ipv6_properties["IPv6.Configuration"]
|
||||||
|
changed = []
|
||||||
|
for k, v in new.items():
|
||||||
|
if conf.get(k) != v:
|
||||||
|
changed.append(k)
|
||||||
|
log.debug("Changed IPv6: %s", ", ".join(changed))
|
||||||
|
if not changed:
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_reply():
|
||||||
|
log.info("Set IPv6=%s", new)
|
||||||
|
|
||||||
|
def on_error(exc):
|
||||||
|
log.error("Failed to set IPv6.Configuration=%s: %s", new, exc)
|
||||||
|
popup_error(self.obj, "Failed to Apply IPv6",
|
||||||
|
exc.get_dbus_message())
|
||||||
|
self.bus_obj.SetProperty(
|
||||||
|
"IPv6.Configuration", new,
|
||||||
|
reply_handler=on_reply, error_handler=on_error
|
||||||
|
)
|
||||||
|
|
||||||
|
def _on_ipv6_method(self, obj, item):
|
||||||
|
if item.text == "Automatic":
|
||||||
|
method = "auto"
|
||||||
|
elif item.text == "Manual":
|
||||||
|
method = "manual"
|
||||||
|
elif item.text == "Off":
|
||||||
|
method = "off"
|
||||||
|
conf = self.ipv6_properties["IPv6.Configuration"]
|
||||||
|
|
||||||
|
editable = (method == "manual") and (not self.immutable)
|
||||||
|
self.ipv6_address.editable = editable
|
||||||
|
self.ipv6_prefix_length.editable = editable
|
||||||
|
self.ipv6_gateway.editable = editable
|
||||||
|
# privacy has only meaning if Method is set to "auto"
|
||||||
|
editable = (method == "auto") and (not self.immutable)
|
||||||
|
self.ipv6_privacy.disabled = not editable
|
||||||
|
|
||||||
|
if method == conf["Method"]:
|
||||||
|
return
|
||||||
|
self._ipv6_apply()
|
||||||
|
|
||||||
|
def _on_ipv6_privacy(self, obj, item):
|
||||||
|
if item.text == "Disabled":
|
||||||
|
privacy = "disabled"
|
||||||
|
elif item.text == "Enabled":
|
||||||
|
privacy = "enabled"
|
||||||
|
elif item.text == "Prefered":
|
||||||
|
privacy = "prefered"
|
||||||
|
conf = self.ipv6_properties["IPv6.Configuration"]
|
||||||
|
if privacy == conf["Privacy"]:
|
||||||
|
return
|
||||||
|
self._ipv6_apply()
|
||||||
|
|
||||||
|
def _on_ipv6_property_changed(self, obj):
|
||||||
|
self._ipv6_apply()
|
||||||
|
|
||||||
|
def _on_ipv6_property_unfocused(self, obj):
|
||||||
|
used = self.ipv6_properties["IPv6"]
|
||||||
|
conf = self.ipv6_properties["IPv6.Configuration"]
|
||||||
|
|
||||||
|
def get_val(name):
|
||||||
|
v = used.get(name) or conf.get(name)
|
||||||
|
if not v:
|
||||||
|
return ""
|
||||||
|
return str(v)
|
||||||
|
self.ipv6_address.text = get_val("Address")
|
||||||
|
self.ipv6_prefix_length.text = get_val("PrefixLength")
|
||||||
|
self.ipv6_gateway.text = get_val("Gateway")
|
||||||
|
#self.ipv6_privacy.text = get_val("Privacy")
|
||||||
|
|
||||||
def _on_proxy_method(self, obj, item):
|
def _on_proxy_method(self, obj, item):
|
||||||
if item.text == "Direct":
|
if item.text == "Direct":
|
||||||
method = "direct"
|
method = "direct"
|
||||||
|
|
Loading…
Reference in New Issue