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