Add support for IPv6
This commit is contained in:
parent
4702710f7c
commit
18e7be6bf8
210
econnman-bin.in
210
econnman-bin.in
|
@ -56,10 +56,10 @@ except:
|
|||
|
||||
dbus_ml = DBusEcoreMainLoop()
|
||||
bus = dbus.SystemBus(mainloop=dbus_ml)
|
||||
log = logging.getLogger("econnman")
|
||||
log = logging.getLogger("econnman-bin")
|
||||
log_handler = logging.StreamHandler()
|
||||
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.addHandler(log_handler)
|
||||
|
@ -347,6 +347,20 @@ class ObjectView(object):
|
|||
sc.callback_changed_add(callback)
|
||||
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):
|
||||
fr = Frame(box)
|
||||
fr.size_hint_weight = EXPAND_HORIZ
|
||||
|
@ -925,6 +939,28 @@ class ServiceView(ObjectView):
|
|||
"""
|
||||
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"),
|
||||
("Interface", "eth_iface"),
|
||||
("Address", "eth_addr"),
|
||||
|
@ -932,15 +968,6 @@ class ServiceView(ObjectView):
|
|||
("Speed", "eth_speed"),
|
||||
("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 = (
|
||||
"connect",
|
||||
|
@ -959,6 +986,7 @@ class ServiceView(ObjectView):
|
|||
"domains_label",
|
||||
"domains_entry",
|
||||
"ipv4_frame",
|
||||
"ipv6_frame",
|
||||
"proxy_frame",
|
||||
"ethernet_frame",
|
||||
"vpn_frame",
|
||||
|
@ -1033,10 +1061,22 @@ class ServiceView(ObjectView):
|
|||
en.callback_unfocused_add(self._on_ipv4_property_unfocused)
|
||||
setattr(self, attr, en)
|
||||
|
||||
# section: IPv6: similar to ipv4? refactor ipv4?
|
||||
if properties.get("IPv6"):
|
||||
# section: IPv6
|
||||
self.ipv6_properties = {"IPv6": {}, "IPv6.Configuration": {}}
|
||||
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
|
||||
# - direct: nothing
|
||||
|
@ -1186,6 +1226,11 @@ class ServiceView(ObjectView):
|
|||
self.ipv4_address.disabled = value
|
||||
self.ipv4_netmask.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
|
||||
elif name == "Favorite":
|
||||
value = bool(value)
|
||||
|
@ -1250,6 +1295,47 @@ class ServiceView(ObjectView):
|
|||
self.ipv4_method_items["Off"].selected = True
|
||||
elif 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"):
|
||||
self.proxy_properties[name] = value
|
||||
|
@ -1437,6 +1523,102 @@ class ServiceView(ObjectView):
|
|||
self.ipv4_netmask.text = get_val("Netmask")
|
||||
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):
|
||||
if item.text == "Direct":
|
||||
method = "direct"
|
||||
|
|
Loading…
Reference in New Issue