xref: /aosp_15_r20/external/libnl/python/netlink/route/address.py (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker#
2*4dc78e53SAndroid Build Coastguard Worker# Copyright (c) 2011 Thomas Graf <[email protected]>
3*4dc78e53SAndroid Build Coastguard Worker#
4*4dc78e53SAndroid Build Coastguard Worker
5*4dc78e53SAndroid Build Coastguard Worker"""Module providing access to network addresses
6*4dc78e53SAndroid Build Coastguard Worker"""
7*4dc78e53SAndroid Build Coastguard Worker
8*4dc78e53SAndroid Build Coastguard Workerfrom __future__ import absolute_import
9*4dc78e53SAndroid Build Coastguard Worker
10*4dc78e53SAndroid Build Coastguard Worker
11*4dc78e53SAndroid Build Coastguard Worker__version__ = "1.0"
12*4dc78e53SAndroid Build Coastguard Worker__all__ = ["AddressCache", "Address"]
13*4dc78e53SAndroid Build Coastguard Worker
14*4dc78e53SAndroid Build Coastguard Workerimport datetime
15*4dc78e53SAndroid Build Coastguard Workerfrom .. import core as netlink
16*4dc78e53SAndroid Build Coastguard Workerfrom . import capi as capi
17*4dc78e53SAndroid Build Coastguard Workerfrom . import link as Link
18*4dc78e53SAndroid Build Coastguard Workerfrom .. import util as util
19*4dc78e53SAndroid Build Coastguard Worker
20*4dc78e53SAndroid Build Coastguard Worker
21*4dc78e53SAndroid Build Coastguard Workerclass AddressCache(netlink.Cache):
22*4dc78e53SAndroid Build Coastguard Worker    """Cache containing network addresses"""
23*4dc78e53SAndroid Build Coastguard Worker
24*4dc78e53SAndroid Build Coastguard Worker    def __init__(self, cache=None):
25*4dc78e53SAndroid Build Coastguard Worker        if not cache:
26*4dc78e53SAndroid Build Coastguard Worker            cache = self._alloc_cache_name("route/addr")
27*4dc78e53SAndroid Build Coastguard Worker
28*4dc78e53SAndroid Build Coastguard Worker        self._protocol = netlink.NETLINK_ROUTE
29*4dc78e53SAndroid Build Coastguard Worker        self._nl_cache = cache
30*4dc78e53SAndroid Build Coastguard Worker
31*4dc78e53SAndroid Build Coastguard Worker    def __getitem__(self, key):
32*4dc78e53SAndroid Build Coastguard Worker        # Using ifindex=0 here implies that the local address itself
33*4dc78e53SAndroid Build Coastguard Worker        # is unique, otherwise the first occurence is returned.
34*4dc78e53SAndroid Build Coastguard Worker        return self.lookup(0, key)
35*4dc78e53SAndroid Build Coastguard Worker
36*4dc78e53SAndroid Build Coastguard Worker    def lookup(self, ifindex, local):
37*4dc78e53SAndroid Build Coastguard Worker        if type(local) is str:
38*4dc78e53SAndroid Build Coastguard Worker            local = netlink.AbstractAddress(local)
39*4dc78e53SAndroid Build Coastguard Worker
40*4dc78e53SAndroid Build Coastguard Worker        addr = capi.rtnl_addr_get(self._nl_cache, ifindex, local._nl_addr)
41*4dc78e53SAndroid Build Coastguard Worker        if addr is None:
42*4dc78e53SAndroid Build Coastguard Worker            raise KeyError()
43*4dc78e53SAndroid Build Coastguard Worker
44*4dc78e53SAndroid Build Coastguard Worker        return Address._from_capi(addr)
45*4dc78e53SAndroid Build Coastguard Worker
46*4dc78e53SAndroid Build Coastguard Worker    @staticmethod
47*4dc78e53SAndroid Build Coastguard Worker    def _new_object(obj):
48*4dc78e53SAndroid Build Coastguard Worker        return Address(obj)
49*4dc78e53SAndroid Build Coastguard Worker
50*4dc78e53SAndroid Build Coastguard Worker    @staticmethod
51*4dc78e53SAndroid Build Coastguard Worker    def _new_cache(cache):
52*4dc78e53SAndroid Build Coastguard Worker        return AddressCache(cache=cache)
53*4dc78e53SAndroid Build Coastguard Worker
54*4dc78e53SAndroid Build Coastguard Worker
55*4dc78e53SAndroid Build Coastguard Workerclass Address(netlink.Object):
56*4dc78e53SAndroid Build Coastguard Worker    """Network address"""
57*4dc78e53SAndroid Build Coastguard Worker
58*4dc78e53SAndroid Build Coastguard Worker    def __init__(self, obj=None):
59*4dc78e53SAndroid Build Coastguard Worker        netlink.Object.__init__(self, "route/addr", "address", obj)
60*4dc78e53SAndroid Build Coastguard Worker        self._rtnl_addr = self._obj2type(self._nl_object)
61*4dc78e53SAndroid Build Coastguard Worker
62*4dc78e53SAndroid Build Coastguard Worker    @classmethod
63*4dc78e53SAndroid Build Coastguard Worker    def _from_capi(cls, obj):
64*4dc78e53SAndroid Build Coastguard Worker        return cls(capi.addr2obj(obj))
65*4dc78e53SAndroid Build Coastguard Worker
66*4dc78e53SAndroid Build Coastguard Worker    @staticmethod
67*4dc78e53SAndroid Build Coastguard Worker    def _obj2type(obj):
68*4dc78e53SAndroid Build Coastguard Worker        return capi.obj2addr(obj)
69*4dc78e53SAndroid Build Coastguard Worker
70*4dc78e53SAndroid Build Coastguard Worker    def __cmp__(self, other):
71*4dc78e53SAndroid Build Coastguard Worker        # sort by:
72*4dc78e53SAndroid Build Coastguard Worker        #    1. network link
73*4dc78e53SAndroid Build Coastguard Worker        #    2. address family
74*4dc78e53SAndroid Build Coastguard Worker        #    3. local address (including prefixlen)
75*4dc78e53SAndroid Build Coastguard Worker        diff = self.ifindex - other.ifindex
76*4dc78e53SAndroid Build Coastguard Worker
77*4dc78e53SAndroid Build Coastguard Worker        if diff == 0:
78*4dc78e53SAndroid Build Coastguard Worker            diff = self.family - other.family
79*4dc78e53SAndroid Build Coastguard Worker            if diff == 0:
80*4dc78e53SAndroid Build Coastguard Worker                diff = capi.nl_addr_cmp(self.local, other.local)
81*4dc78e53SAndroid Build Coastguard Worker
82*4dc78e53SAndroid Build Coastguard Worker        return diff
83*4dc78e53SAndroid Build Coastguard Worker
84*4dc78e53SAndroid Build Coastguard Worker    @staticmethod
85*4dc78e53SAndroid Build Coastguard Worker    def _new_instance(obj):
86*4dc78e53SAndroid Build Coastguard Worker        return Address(obj)
87*4dc78e53SAndroid Build Coastguard Worker
88*4dc78e53SAndroid Build Coastguard Worker    @property
89*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
90*4dc78e53SAndroid Build Coastguard Worker    def ifindex(self):
91*4dc78e53SAndroid Build Coastguard Worker        """interface index"""
92*4dc78e53SAndroid Build Coastguard Worker        return capi.rtnl_addr_get_ifindex(self._rtnl_addr)
93*4dc78e53SAndroid Build Coastguard Worker
94*4dc78e53SAndroid Build Coastguard Worker    @ifindex.setter
95*4dc78e53SAndroid Build Coastguard Worker    def ifindex(self, value):
96*4dc78e53SAndroid Build Coastguard Worker        link = Link.resolve(value)
97*4dc78e53SAndroid Build Coastguard Worker        if not link:
98*4dc78e53SAndroid Build Coastguard Worker            raise ValueError()
99*4dc78e53SAndroid Build Coastguard Worker
100*4dc78e53SAndroid Build Coastguard Worker        self.link = link
101*4dc78e53SAndroid Build Coastguard Worker
102*4dc78e53SAndroid Build Coastguard Worker    @property
103*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, fmt=util.string)
104*4dc78e53SAndroid Build Coastguard Worker    def link(self):
105*4dc78e53SAndroid Build Coastguard Worker        link = capi.rtnl_addr_get_link(self._rtnl_addr)
106*4dc78e53SAndroid Build Coastguard Worker        if not link:
107*4dc78e53SAndroid Build Coastguard Worker            return None
108*4dc78e53SAndroid Build Coastguard Worker
109*4dc78e53SAndroid Build Coastguard Worker        return Link.Link.from_capi(link)
110*4dc78e53SAndroid Build Coastguard Worker
111*4dc78e53SAndroid Build Coastguard Worker    @link.setter
112*4dc78e53SAndroid Build Coastguard Worker    def link(self, value):
113*4dc78e53SAndroid Build Coastguard Worker        if type(value) is str:
114*4dc78e53SAndroid Build Coastguard Worker            try:
115*4dc78e53SAndroid Build Coastguard Worker                value = Link.resolve(value)
116*4dc78e53SAndroid Build Coastguard Worker            except KeyError:
117*4dc78e53SAndroid Build Coastguard Worker                raise ValueError()
118*4dc78e53SAndroid Build Coastguard Worker
119*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_link(self._rtnl_addr, value._rtnl_link)
120*4dc78e53SAndroid Build Coastguard Worker
121*4dc78e53SAndroid Build Coastguard Worker        # ifindex is immutable but we assume that if _orig does not
122*4dc78e53SAndroid Build Coastguard Worker        # have an ifindex specified, it was meant to be given here
123*4dc78e53SAndroid Build Coastguard Worker        if capi.rtnl_addr_get_ifindex(self._orig) == 0:
124*4dc78e53SAndroid Build Coastguard Worker            capi.rtnl_addr_set_ifindex(self._orig, value.ifindex)
125*4dc78e53SAndroid Build Coastguard Worker
126*4dc78e53SAndroid Build Coastguard Worker    @property
127*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, fmt=util.string)
128*4dc78e53SAndroid Build Coastguard Worker    def label(self):
129*4dc78e53SAndroid Build Coastguard Worker        """address label"""
130*4dc78e53SAndroid Build Coastguard Worker        return capi.rtnl_addr_get_label(self._rtnl_addr)
131*4dc78e53SAndroid Build Coastguard Worker
132*4dc78e53SAndroid Build Coastguard Worker    @label.setter
133*4dc78e53SAndroid Build Coastguard Worker    def label(self, value):
134*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_label(self._rtnl_addr, value)
135*4dc78e53SAndroid Build Coastguard Worker
136*4dc78e53SAndroid Build Coastguard Worker    @property
137*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, fmt=util.string)
138*4dc78e53SAndroid Build Coastguard Worker    def flags(self):
139*4dc78e53SAndroid Build Coastguard Worker        """Flags
140*4dc78e53SAndroid Build Coastguard Worker
141*4dc78e53SAndroid Build Coastguard Worker        Setting this property will *Not* reset flags to value you supply in
142*4dc78e53SAndroid Build Coastguard Worker
143*4dc78e53SAndroid Build Coastguard Worker        Examples:
144*4dc78e53SAndroid Build Coastguard Worker        addr.flags = '+xxx' # add xxx flag
145*4dc78e53SAndroid Build Coastguard Worker        addr.flags = 'xxx'  # exactly the same
146*4dc78e53SAndroid Build Coastguard Worker        addr.flags = '-xxx' # remove xxx flag
147*4dc78e53SAndroid Build Coastguard Worker        addr.flags = [ '+xxx', '-yyy' ] # list operation
148*4dc78e53SAndroid Build Coastguard Worker        """
149*4dc78e53SAndroid Build Coastguard Worker        flags = capi.rtnl_addr_get_flags(self._rtnl_addr)
150*4dc78e53SAndroid Build Coastguard Worker        return capi.rtnl_addr_flags2str(flags, 256)[0].split(",")
151*4dc78e53SAndroid Build Coastguard Worker
152*4dc78e53SAndroid Build Coastguard Worker    def _set_flag(self, flag):
153*4dc78e53SAndroid Build Coastguard Worker        if flag.startswith("-"):
154*4dc78e53SAndroid Build Coastguard Worker            i = capi.rtnl_addr_str2flags(flag[1:])
155*4dc78e53SAndroid Build Coastguard Worker            capi.rtnl_addr_unset_flags(self._rtnl_addr, i)
156*4dc78e53SAndroid Build Coastguard Worker        elif flag.startswith("+"):
157*4dc78e53SAndroid Build Coastguard Worker            i = capi.rtnl_addr_str2flags(flag[1:])
158*4dc78e53SAndroid Build Coastguard Worker            capi.rtnl_addr_set_flags(self._rtnl_addr, i)
159*4dc78e53SAndroid Build Coastguard Worker        else:
160*4dc78e53SAndroid Build Coastguard Worker            i = capi.rtnl_addr_str2flags(flag)
161*4dc78e53SAndroid Build Coastguard Worker            capi.rtnl_addr_set_flags(self._rtnl_addr, i)
162*4dc78e53SAndroid Build Coastguard Worker
163*4dc78e53SAndroid Build Coastguard Worker    @flags.setter
164*4dc78e53SAndroid Build Coastguard Worker    def flags(self, value):
165*4dc78e53SAndroid Build Coastguard Worker        if type(value) is list:
166*4dc78e53SAndroid Build Coastguard Worker            for flag in value:
167*4dc78e53SAndroid Build Coastguard Worker                self._set_flag(flag)
168*4dc78e53SAndroid Build Coastguard Worker        else:
169*4dc78e53SAndroid Build Coastguard Worker            self._set_flag(value)
170*4dc78e53SAndroid Build Coastguard Worker
171*4dc78e53SAndroid Build Coastguard Worker    @property
172*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
173*4dc78e53SAndroid Build Coastguard Worker    def family(self):
174*4dc78e53SAndroid Build Coastguard Worker        """Address family"""
175*4dc78e53SAndroid Build Coastguard Worker        fam = capi.rtnl_addr_get_family(self._rtnl_addr)
176*4dc78e53SAndroid Build Coastguard Worker        return netlink.AddressFamily(fam)
177*4dc78e53SAndroid Build Coastguard Worker
178*4dc78e53SAndroid Build Coastguard Worker    @family.setter
179*4dc78e53SAndroid Build Coastguard Worker    def family(self, value):
180*4dc78e53SAndroid Build Coastguard Worker        if not isinstance(value, netlink.AddressFamily):
181*4dc78e53SAndroid Build Coastguard Worker            value = netlink.AddressFamily(value)
182*4dc78e53SAndroid Build Coastguard Worker
183*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_family(self._rtnl_addr, int(value))
184*4dc78e53SAndroid Build Coastguard Worker
185*4dc78e53SAndroid Build Coastguard Worker    @property
186*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=int, fmt=util.num)
187*4dc78e53SAndroid Build Coastguard Worker    def scope(self):
188*4dc78e53SAndroid Build Coastguard Worker        """Address scope"""
189*4dc78e53SAndroid Build Coastguard Worker        scope = capi.rtnl_addr_get_scope(self._rtnl_addr)
190*4dc78e53SAndroid Build Coastguard Worker        return capi.rtnl_scope2str(scope, 32)[0]
191*4dc78e53SAndroid Build Coastguard Worker
192*4dc78e53SAndroid Build Coastguard Worker    @scope.setter
193*4dc78e53SAndroid Build Coastguard Worker    def scope(self, value):
194*4dc78e53SAndroid Build Coastguard Worker        if type(value) is str:
195*4dc78e53SAndroid Build Coastguard Worker            value = capi.rtnl_str2scope(value)
196*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_scope(self._rtnl_addr, value)
197*4dc78e53SAndroid Build Coastguard Worker
198*4dc78e53SAndroid Build Coastguard Worker    @property
199*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, immutable=True, fmt=util.addr)
200*4dc78e53SAndroid Build Coastguard Worker    def local(self):
201*4dc78e53SAndroid Build Coastguard Worker        """Local address"""
202*4dc78e53SAndroid Build Coastguard Worker        a = capi.rtnl_addr_get_local(self._rtnl_addr)
203*4dc78e53SAndroid Build Coastguard Worker        return netlink.AbstractAddress(a)
204*4dc78e53SAndroid Build Coastguard Worker
205*4dc78e53SAndroid Build Coastguard Worker    @local.setter
206*4dc78e53SAndroid Build Coastguard Worker    def local(self, value):
207*4dc78e53SAndroid Build Coastguard Worker        a = netlink.AbstractAddress(value)
208*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_local(self._rtnl_addr, a._nl_addr)
209*4dc78e53SAndroid Build Coastguard Worker
210*4dc78e53SAndroid Build Coastguard Worker        # local is immutable but we assume that if _orig does not
211*4dc78e53SAndroid Build Coastguard Worker        # have a local address specified, it was meant to be given here
212*4dc78e53SAndroid Build Coastguard Worker        if capi.rtnl_addr_get_local(self._orig) is None:
213*4dc78e53SAndroid Build Coastguard Worker            capi.rtnl_addr_set_local(self._orig, a._nl_addr)
214*4dc78e53SAndroid Build Coastguard Worker
215*4dc78e53SAndroid Build Coastguard Worker    @property
216*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, fmt=util.addr)
217*4dc78e53SAndroid Build Coastguard Worker    def peer(self):
218*4dc78e53SAndroid Build Coastguard Worker        """Peer address"""
219*4dc78e53SAndroid Build Coastguard Worker        a = capi.rtnl_addr_get_peer(self._rtnl_addr)
220*4dc78e53SAndroid Build Coastguard Worker        return netlink.AbstractAddress(a)
221*4dc78e53SAndroid Build Coastguard Worker
222*4dc78e53SAndroid Build Coastguard Worker    @peer.setter
223*4dc78e53SAndroid Build Coastguard Worker    def peer(self, value):
224*4dc78e53SAndroid Build Coastguard Worker        a = netlink.AbstractAddress(value)
225*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_peer(self._rtnl_addr, a._nl_addr)
226*4dc78e53SAndroid Build Coastguard Worker
227*4dc78e53SAndroid Build Coastguard Worker    @property
228*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, fmt=util.addr)
229*4dc78e53SAndroid Build Coastguard Worker    def broadcast(self):
230*4dc78e53SAndroid Build Coastguard Worker        """Broadcast address"""
231*4dc78e53SAndroid Build Coastguard Worker        a = capi.rtnl_addr_get_broadcast(self._rtnl_addr)
232*4dc78e53SAndroid Build Coastguard Worker        return netlink.AbstractAddress(a)
233*4dc78e53SAndroid Build Coastguard Worker
234*4dc78e53SAndroid Build Coastguard Worker    @broadcast.setter
235*4dc78e53SAndroid Build Coastguard Worker    def broadcast(self, value):
236*4dc78e53SAndroid Build Coastguard Worker        a = netlink.AbstractAddress(value)
237*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_broadcast(self._rtnl_addr, a._nl_addr)
238*4dc78e53SAndroid Build Coastguard Worker
239*4dc78e53SAndroid Build Coastguard Worker    @property
240*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, fmt=util.addr)
241*4dc78e53SAndroid Build Coastguard Worker    def multicast(self):
242*4dc78e53SAndroid Build Coastguard Worker        """multicast address"""
243*4dc78e53SAndroid Build Coastguard Worker        a = capi.rtnl_addr_get_multicast(self._rtnl_addr)
244*4dc78e53SAndroid Build Coastguard Worker        return netlink.AbstractAddress(a)
245*4dc78e53SAndroid Build Coastguard Worker
246*4dc78e53SAndroid Build Coastguard Worker    @multicast.setter
247*4dc78e53SAndroid Build Coastguard Worker    def multicast(self, value):
248*4dc78e53SAndroid Build Coastguard Worker        try:
249*4dc78e53SAndroid Build Coastguard Worker            a = netlink.AbstractAddress(value)
250*4dc78e53SAndroid Build Coastguard Worker        except ValueError as err:
251*4dc78e53SAndroid Build Coastguard Worker            raise AttributeError("multicast", err)
252*4dc78e53SAndroid Build Coastguard Worker
253*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_multicast(self._rtnl_addr, a._nl_addr)
254*4dc78e53SAndroid Build Coastguard Worker
255*4dc78e53SAndroid Build Coastguard Worker    @property
256*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=str, fmt=util.addr)
257*4dc78e53SAndroid Build Coastguard Worker    def anycast(self):
258*4dc78e53SAndroid Build Coastguard Worker        """anycast address"""
259*4dc78e53SAndroid Build Coastguard Worker        a = capi.rtnl_addr_get_anycast(self._rtnl_addr)
260*4dc78e53SAndroid Build Coastguard Worker        return netlink.AbstractAddress(a)
261*4dc78e53SAndroid Build Coastguard Worker
262*4dc78e53SAndroid Build Coastguard Worker    @anycast.setter
263*4dc78e53SAndroid Build Coastguard Worker    def anycast(self, value):
264*4dc78e53SAndroid Build Coastguard Worker        a = netlink.AbstractAddress(value)
265*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_anycast(self._rtnl_addr, a._nl_addr)
266*4dc78e53SAndroid Build Coastguard Worker
267*4dc78e53SAndroid Build Coastguard Worker    @property
268*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
269*4dc78e53SAndroid Build Coastguard Worker    def valid_lifetime(self):
270*4dc78e53SAndroid Build Coastguard Worker        """Valid lifetime"""
271*4dc78e53SAndroid Build Coastguard Worker        msecs = capi.rtnl_addr_get_valid_lifetime(self._rtnl_addr)
272*4dc78e53SAndroid Build Coastguard Worker        if msecs == 0xFFFFFFFF:
273*4dc78e53SAndroid Build Coastguard Worker            return None
274*4dc78e53SAndroid Build Coastguard Worker        else:
275*4dc78e53SAndroid Build Coastguard Worker            return datetime.timedelta(seconds=msecs)
276*4dc78e53SAndroid Build Coastguard Worker
277*4dc78e53SAndroid Build Coastguard Worker    @valid_lifetime.setter
278*4dc78e53SAndroid Build Coastguard Worker    def valid_lifetime(self, value):
279*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_valid_lifetime(self._rtnl_addr, int(value))
280*4dc78e53SAndroid Build Coastguard Worker
281*4dc78e53SAndroid Build Coastguard Worker    @property
282*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
283*4dc78e53SAndroid Build Coastguard Worker    def preferred_lifetime(self):
284*4dc78e53SAndroid Build Coastguard Worker        """Preferred lifetime"""
285*4dc78e53SAndroid Build Coastguard Worker        msecs = capi.rtnl_addr_get_preferred_lifetime(self._rtnl_addr)
286*4dc78e53SAndroid Build Coastguard Worker        if msecs == 0xFFFFFFFF:
287*4dc78e53SAndroid Build Coastguard Worker            return None
288*4dc78e53SAndroid Build Coastguard Worker        else:
289*4dc78e53SAndroid Build Coastguard Worker            return datetime.timedelta(seconds=msecs)
290*4dc78e53SAndroid Build Coastguard Worker
291*4dc78e53SAndroid Build Coastguard Worker    @preferred_lifetime.setter
292*4dc78e53SAndroid Build Coastguard Worker    def preferred_lifetime(self, value):
293*4dc78e53SAndroid Build Coastguard Worker        capi.rtnl_addr_set_preferred_lifetime(self._rtnl_addr, int(value))
294*4dc78e53SAndroid Build Coastguard Worker
295*4dc78e53SAndroid Build Coastguard Worker    @property
296*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
297*4dc78e53SAndroid Build Coastguard Worker    def create_time(self):
298*4dc78e53SAndroid Build Coastguard Worker        """Creation time"""
299*4dc78e53SAndroid Build Coastguard Worker        hsec = capi.rtnl_addr_get_create_time(self._rtnl_addr)
300*4dc78e53SAndroid Build Coastguard Worker        return datetime.timedelta(milliseconds=10 * hsec)
301*4dc78e53SAndroid Build Coastguard Worker
302*4dc78e53SAndroid Build Coastguard Worker    @property
303*4dc78e53SAndroid Build Coastguard Worker    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
304*4dc78e53SAndroid Build Coastguard Worker    def last_update(self):
305*4dc78e53SAndroid Build Coastguard Worker        """Last update"""
306*4dc78e53SAndroid Build Coastguard Worker        hsec = capi.rtnl_addr_get_last_update_time(self._rtnl_addr)
307*4dc78e53SAndroid Build Coastguard Worker        return datetime.timedelta(milliseconds=10 * hsec)
308*4dc78e53SAndroid Build Coastguard Worker
309*4dc78e53SAndroid Build Coastguard Worker    def add(self, socket=None, flags=None):
310*4dc78e53SAndroid Build Coastguard Worker        if not socket:
311*4dc78e53SAndroid Build Coastguard Worker            socket = netlink.lookup_socket(netlink.NETLINK_ROUTE)
312*4dc78e53SAndroid Build Coastguard Worker
313*4dc78e53SAndroid Build Coastguard Worker        if not flags:
314*4dc78e53SAndroid Build Coastguard Worker            flags = netlink.NLM_F_CREATE
315*4dc78e53SAndroid Build Coastguard Worker
316*4dc78e53SAndroid Build Coastguard Worker        ret = capi.rtnl_addr_add(socket._sock, self._rtnl_addr, flags)
317*4dc78e53SAndroid Build Coastguard Worker        if ret < 0:
318*4dc78e53SAndroid Build Coastguard Worker            raise netlink.KernelError(ret)
319*4dc78e53SAndroid Build Coastguard Worker
320*4dc78e53SAndroid Build Coastguard Worker    def delete(self, socket, flags=0):
321*4dc78e53SAndroid Build Coastguard Worker        """Attempt to delete this address in the kernel"""
322*4dc78e53SAndroid Build Coastguard Worker        ret = capi.rtnl_addr_delete(socket._sock, self._rtnl_addr, flags)
323*4dc78e53SAndroid Build Coastguard Worker        if ret < 0:
324*4dc78e53SAndroid Build Coastguard Worker            raise netlink.KernelError(ret)
325*4dc78e53SAndroid Build Coastguard Worker
326*4dc78e53SAndroid Build Coastguard Worker    ###################################################################
327*4dc78e53SAndroid Build Coastguard Worker    # private properties
328*4dc78e53SAndroid Build Coastguard Worker    #
329*4dc78e53SAndroid Build Coastguard Worker    # Used for formatting output. USE AT OWN RISK
330*4dc78e53SAndroid Build Coastguard Worker    @property
331*4dc78e53SAndroid Build Coastguard Worker    def _flags(self):
332*4dc78e53SAndroid Build Coastguard Worker        return ",".join(self.flags)
333*4dc78e53SAndroid Build Coastguard Worker
334*4dc78e53SAndroid Build Coastguard Worker    def format(self, details=False, stats=False, nodev=False, indent=""):
335*4dc78e53SAndroid Build Coastguard Worker        """Return address as formatted text"""
336*4dc78e53SAndroid Build Coastguard Worker        fmt = util.MyFormatter(self, indent)
337*4dc78e53SAndroid Build Coastguard Worker
338*4dc78e53SAndroid Build Coastguard Worker        buf = fmt.format("{a|local!b}")
339*4dc78e53SAndroid Build Coastguard Worker
340*4dc78e53SAndroid Build Coastguard Worker        if not nodev:
341*4dc78e53SAndroid Build Coastguard Worker            buf += fmt.format(" {a|ifindex}")
342*4dc78e53SAndroid Build Coastguard Worker
343*4dc78e53SAndroid Build Coastguard Worker        buf += fmt.format(" {a|scope}")
344*4dc78e53SAndroid Build Coastguard Worker
345*4dc78e53SAndroid Build Coastguard Worker        if self.label:
346*4dc78e53SAndroid Build Coastguard Worker            buf += fmt.format(' "{a|label}"')
347*4dc78e53SAndroid Build Coastguard Worker
348*4dc78e53SAndroid Build Coastguard Worker        buf += fmt.format(" <{a|_flags}>")
349*4dc78e53SAndroid Build Coastguard Worker
350*4dc78e53SAndroid Build Coastguard Worker        if details:
351*4dc78e53SAndroid Build Coastguard Worker            buf += fmt.nl("\t{t|broadcast} {t|multicast}") + fmt.nl(
352*4dc78e53SAndroid Build Coastguard Worker                "\t{t|peer} {t|anycast}"
353*4dc78e53SAndroid Build Coastguard Worker            )
354*4dc78e53SAndroid Build Coastguard Worker
355*4dc78e53SAndroid Build Coastguard Worker            if self.valid_lifetime:
356*4dc78e53SAndroid Build Coastguard Worker                buf += fmt.nl("\t{s|valid-lifetime!k} " "{a|valid_lifetime}")
357*4dc78e53SAndroid Build Coastguard Worker
358*4dc78e53SAndroid Build Coastguard Worker            if self.preferred_lifetime:
359*4dc78e53SAndroid Build Coastguard Worker                buf += fmt.nl("\t{s|preferred-lifetime!k} " "{a|preferred_lifetime}")
360*4dc78e53SAndroid Build Coastguard Worker
361*4dc78e53SAndroid Build Coastguard Worker        if stats and (self.create_time or self.last_update):
362*4dc78e53SAndroid Build Coastguard Worker            buf += self.nl(
363*4dc78e53SAndroid Build Coastguard Worker                "\t{s|created!k} {a|create_time}" " {s|last-updated!k} {a|last_update}"
364*4dc78e53SAndroid Build Coastguard Worker            )
365*4dc78e53SAndroid Build Coastguard Worker
366*4dc78e53SAndroid Build Coastguard Worker        return buf
367