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 GENL_ID_CTRL = 16 16 17 18def roundup2(val: int, num: int) -> int: 19 if val % num: 20 return (val | (num - 1)) + 1 21 else: 22 return val 23 24 25def align4(val: int) -> int: 26 return roundup2(val, 4) 27 28 29def enum_or_int(val) -> int: 30 if isinstance(val, Enum): 31 return val.value 32 return val 33 34 35class AttrDescr(NamedTuple): 36 val: Enum 37 cls: "NlAttr" 38 child_map: Any = None 39 40 41def prepare_attrs_map(attrs: List[AttrDescr]) -> Dict[str, Dict]: 42 ret = {} 43 for ad in attrs: 44 ret[ad.val.value] = {"ad": ad} 45 if ad.child_map: 46 ret[ad.val.value]["child"] = prepare_attrs_map(ad.child_map) 47 return ret 48 49 50def build_propmap(cls): 51 ret = {} 52 for prop in dir(cls): 53 if not prop.startswith("_"): 54 ret[getattr(cls, prop).value] = prop 55 return ret 56 57 58def get_bitmask_map(propmap, val): 59 v = 1 60 ret = {} 61 while val: 62 if v & val: 63 if v in propmap: 64 ret[v] = propmap[v] 65 else: 66 ret[v] = hex(v) 67 val -= v 68 v *= 2 69 return ret 70 71 72def get_bitmask_str(cls, val): 73 if isinstance(cls, type): 74 pmap = build_propmap(cls) 75 else: 76 pmap = {} 77 for _cls in cls: 78 pmap.update(build_propmap(_cls)) 79 bmap = get_bitmask_map(pmap, val) 80 return ",".join([v for k, v in bmap.items()]) 81