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