xref: /freebsd/tests/atf_python/sys/netlink/utils.py (revision 54b955f4)
1fee65b7eSAlexander V. Chernikov#!/usr/local/bin/python3
2fee65b7eSAlexander V. Chernikovfrom enum import Enum
3fee65b7eSAlexander V. Chernikovfrom typing import Any
4fee65b7eSAlexander V. Chernikovfrom typing import Dict
5fee65b7eSAlexander V. Chernikovfrom typing import List
6fee65b7eSAlexander V. Chernikovfrom typing import NamedTuple
7fee65b7eSAlexander V. Chernikov
8fee65b7eSAlexander V. Chernikov
9fee65b7eSAlexander V. Chernikovclass NlConst:
10fee65b7eSAlexander V. Chernikov    AF_NETLINK = 38
11fee65b7eSAlexander V. Chernikov    NETLINK_ROUTE = 0
12fee65b7eSAlexander V. Chernikov    NETLINK_GENERIC = 16
13fc2538cbSAlexander V. Chernikov    GENL_ID_CTRL = 16
14fee65b7eSAlexander V. Chernikov
15fee65b7eSAlexander V. Chernikov
16fee65b7eSAlexander V. Chernikovdef roundup2(val: int, num: int) -> int:
17fee65b7eSAlexander V. Chernikov    if val % num:
18fee65b7eSAlexander V. Chernikov        return (val | (num - 1)) + 1
19fee65b7eSAlexander V. Chernikov    else:
20fee65b7eSAlexander V. Chernikov        return val
21fee65b7eSAlexander V. Chernikov
22fee65b7eSAlexander V. Chernikov
23fee65b7eSAlexander V. Chernikovdef align4(val: int) -> int:
24fee65b7eSAlexander V. Chernikov    return roundup2(val, 4)
25fee65b7eSAlexander V. Chernikov
26fee65b7eSAlexander V. Chernikov
27fee65b7eSAlexander V. Chernikovdef enum_or_int(val) -> int:
28fee65b7eSAlexander V. Chernikov    if isinstance(val, Enum):
29fee65b7eSAlexander V. Chernikov        return val.value
30fee65b7eSAlexander V. Chernikov    return val
31fee65b7eSAlexander V. Chernikov
32fee65b7eSAlexander V. Chernikov
33fee65b7eSAlexander V. Chernikovclass AttrDescr(NamedTuple):
34fee65b7eSAlexander V. Chernikov    val: Enum
35fee65b7eSAlexander V. Chernikov    cls: "NlAttr"
36fee65b7eSAlexander V. Chernikov    child_map: Any = None
3754b955f4SAlexander V. Chernikov    is_array: bool = False
38fee65b7eSAlexander V. Chernikov
39fee65b7eSAlexander V. Chernikov
40fee65b7eSAlexander V. Chernikovdef prepare_attrs_map(attrs: List[AttrDescr]) -> Dict[str, Dict]:
41fee65b7eSAlexander V. Chernikov    ret = {}
42fee65b7eSAlexander V. Chernikov    for ad in attrs:
43fee65b7eSAlexander V. Chernikov        ret[ad.val.value] = {"ad": ad}
44fee65b7eSAlexander V. Chernikov        if ad.child_map:
45fee65b7eSAlexander V. Chernikov            ret[ad.val.value]["child"] = prepare_attrs_map(ad.child_map)
4654b955f4SAlexander V. Chernikov            ret[ad.val.value]["is_array"] = ad.is_array
47fee65b7eSAlexander V. Chernikov    return ret
48fee65b7eSAlexander V. Chernikov
49fee65b7eSAlexander V. Chernikov
50fee65b7eSAlexander V. Chernikovdef build_propmap(cls):
51fee65b7eSAlexander V. Chernikov    ret = {}
52fee65b7eSAlexander V. Chernikov    for prop in dir(cls):
53fee65b7eSAlexander V. Chernikov        if not prop.startswith("_"):
54fee65b7eSAlexander V. Chernikov            ret[getattr(cls, prop).value] = prop
55fee65b7eSAlexander V. Chernikov    return ret
56fee65b7eSAlexander V. Chernikov
57fee65b7eSAlexander V. Chernikov
58fee65b7eSAlexander V. Chernikovdef get_bitmask_map(propmap, val):
59fee65b7eSAlexander V. Chernikov    v = 1
60fee65b7eSAlexander V. Chernikov    ret = {}
61fee65b7eSAlexander V. Chernikov    while val:
62fee65b7eSAlexander V. Chernikov        if v & val:
63fee65b7eSAlexander V. Chernikov            if v in propmap:
64fee65b7eSAlexander V. Chernikov                ret[v] = propmap[v]
65fee65b7eSAlexander V. Chernikov            else:
66fee65b7eSAlexander V. Chernikov                ret[v] = hex(v)
67fee65b7eSAlexander V. Chernikov            val -= v
68fee65b7eSAlexander V. Chernikov        v *= 2
69fee65b7eSAlexander V. Chernikov    return ret
70fee65b7eSAlexander V. Chernikov
71fee65b7eSAlexander V. Chernikov
72fee65b7eSAlexander V. Chernikovdef get_bitmask_str(cls, val):
73fc2538cbSAlexander V. Chernikov    if isinstance(cls, type):
74fee65b7eSAlexander V. Chernikov        pmap = build_propmap(cls)
75fc2538cbSAlexander V. Chernikov    else:
76fc2538cbSAlexander V. Chernikov        pmap = {}
77fc2538cbSAlexander V. Chernikov        for _cls in cls:
78fc2538cbSAlexander V. Chernikov            pmap.update(build_propmap(_cls))
79fee65b7eSAlexander V. Chernikov    bmap = get_bitmask_map(pmap, val)
80fee65b7eSAlexander V. Chernikov    return ",".join([v for k, v in bmap.items()])
81