PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/extras-3.10/pyroute2/netlink/nfnetlink/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/extras-3.10/pyroute2/netlink/nfnetlink/nftsocket.py |
""" NFTSocket -- low level nftables API See also: pyroute2.nftables """ import struct import threading from pyroute2.netlink import ( NETLINK_NETFILTER, NLM_F_ACK, NLM_F_APPEND, NLM_F_CREATE, NLM_F_DUMP, NLM_F_EXCL, NLM_F_REPLACE, NLM_F_REQUEST, nla, nla_base_string, nlmsg_atoms, ) from pyroute2.netlink.nfnetlink import NFNL_SUBSYS_NFTABLES, nfgen_msg from pyroute2.netlink.nlsocket import NetlinkSocket NFT_MSG_NEWTABLE = 0 NFT_MSG_GETTABLE = 1 NFT_MSG_DELTABLE = 2 NFT_MSG_NEWCHAIN = 3 NFT_MSG_GETCHAIN = 4 NFT_MSG_DELCHAIN = 5 NFT_MSG_NEWRULE = 6 NFT_MSG_GETRULE = 7 NFT_MSG_DELRULE = 8 NFT_MSG_NEWSET = 9 NFT_MSG_GETSET = 10 NFT_MSG_DELSET = 11 NFT_MSG_NEWSETELEM = 12 NFT_MSG_GETSETELEM = 13 NFT_MSG_DELSETELEM = 14 NFT_MSG_NEWGEN = 15 NFT_MSG_GETGEN = 16 NFT_MSG_TRACE = 17 NFT_MSG_NEWOBJ = 18 NFT_MSG_GETOBJ = 19 NFT_MSG_DELOBJ = 20 NFT_MSG_GETOBJ_RESET = 21 NFT_MSG_NEWFLOWTABLE = 22 NFT_MSG_GETFLOWTABLE = 23 NFT_MSG_DELFLOWTABLE = 24 # from nftables/include/datatype.h DATA_TYPE_INVALID = 0 DATA_TYPE_VERDICT = 1 DATA_TYPE_NFPROTO = 2 DATA_TYPE_BITMASK = 3 DATA_TYPE_INTEGER = 4 DATA_TYPE_STRING = 5 DATA_TYPE_LLADDR = 6 DATA_TYPE_IPADDR = 7 DATA_TYPE_IP6ADDR = 8 DATA_TYPE_ETHERADDR = 9 DATA_TYPE_ETHERTYPE = 10 DATA_TYPE_ARPOP = 11 DATA_TYPE_INET_PROTOCOL = 12 DATA_TYPE_INET_SERVICE = 13 DATA_TYPE_ICMP_TYPE = 14 DATA_TYPE_TCP_FLAG = 15 DATA_TYPE_DCCP_PKTTYPE = 16 DATA_TYPE_MH_TYPE = 17 DATA_TYPE_TIME = 18 DATA_TYPE_MARK = 19 DATA_TYPE_IFINDEX = 20 DATA_TYPE_ARPHRD = 21 DATA_TYPE_REALM = 22 DATA_TYPE_CLASSID = 23 DATA_TYPE_UID = 24 DATA_TYPE_GID = 25 DATA_TYPE_CT_STATE = 26 DATA_TYPE_CT_DIR = 27 DATA_TYPE_CT_STATUS = 28 DATA_TYPE_ICMP6_TYPE = 29 DATA_TYPE_CT_LABEL = 30 DATA_TYPE_PKTTYPE = 31 DATA_TYPE_ICMP_CODE = 32 DATA_TYPE_ICMPV6_CODE = 33 DATA_TYPE_ICMPX_CODE = 34 DATA_TYPE_DEVGROUP = 35 DATA_TYPE_DSCP = 36 DATA_TYPE_ECN = 37 DATA_TYPE_FIB_ADDR = 38 DATA_TYPE_BOOLEAN = 39 DATA_TYPE_CT_EVENTBIT = 40 DATA_TYPE_IFNAME = 41 DATA_TYPE_IGMP_TYPE = 42 DATA_TYPE_TIME_DATE = 43 DATA_TYPE_TIME_HOUR = 44 DATA_TYPE_TIME_DAY = 45 DATA_TYPE_CGROUPV2 = 46 # from include/uapi/linux/netfilter.h NFPROTO_INET = 1 NFPROTO_IPV4 = 2 NFPROTO_ARP = 3 NFPROTO_NETDEV = 5 NFPROTO_BRIDGE = 7 NFPROTO_IPV6 = 10 class nftnl_udata(nla_base_string): # TLV structures: # nftnl_udata # <-------- HEADER --------> <------ PAYLOAD ------> # +------------+-------------+- - - - - - - - - - - -+ # | type | len | value | # | (1 byte) | (1 byte) | | # +--------------------------+- - - - - - - - - - - -+ # <-- sizeof(nftnl_udata) -> <-- nftnl_udata->len --> __slots__ = () @classmethod def udata_decode(cls, data): offset = 0 result = [] while offset + 2 < len(data): utype = data[offset] ulen = data[offset + 1] offset += 2 if offset + ulen > len(data): return None # bad decode try: type_name = cls.udata_types[utype] except IndexError: return None # bad decode value = data[offset : offset + ulen] if type_name.endswith("_COMMENT") and value[-1] == 0: value = value[:-1] # remove \x00 c *str result.append((type_name, value)) offset += ulen return result @classmethod def udata_encode(cls, values): value = b"" for type_name, udata in values: if isinstance(udata, str): udata = udata.encode() if type_name.endswith("_COMMENT") and udata[-1] != 0: udata = udata + b"\x00" utype = cls.udata_types.index(type_name) value += struct.pack("BB", utype, len(udata)) + udata return value def decode(self): nla_base_string.decode(self) value = self.udata_decode(self['value']) if value is not None: self.value = value def encode(self): if not isinstance(self.value, (bytes, str)): self['value'] = self.udata_encode(self.value) nla_base_string.encode(self) class nft_map_uint8(nla): ops = {} fields = [('value', 'B')] def decode(self): nla.decode(self) self.value = self.ops.get(self['value']) class nft_map_be32(nft_map_uint8): fields = [('value', '>I')] class nft_map_be32_signed(nft_map_uint8): fields = [('value', '>i')] class nft_flags_be32(nla): fields = [('value', '>I')] ops = None def decode(self): nla.decode(self) self.value = frozenset( o for i, o in enumerate(self.ops) if self['value'] & 1 << i ) def encode(self): value = 0 for i, name in enumerate(self.ops): if name in self.value: value |= 1 << i self["value"] = value nla.encode(self) class nft_flags_be16(nla): fields = [('value', '>H')] ops = None def decode(self): nla.decode(self) self.value = frozenset( o for i, o in enumerate(self.ops) if self['value'] & 1 << i ) class nft_device(nla): class device_attributes(nla): nla_map = ( ('NFTA_DEVICE_UNSPEC', 'none'), ('NFTA_DEVICE_NAME', 'asciiz'), ) class nft_gen_msg(nfgen_msg): nla_map = ( ('NFTA_GEN_UNSPEC', 'none'), ('NFTA_GEN_ID', 'be32'), ('NFTA_GEN_PROC_PID', 'be32'), ('NFTA_GEN_PROC_NAME', 'asciiz'), ) class nft_chain_msg(nfgen_msg): prefix = 'NFTA_CHAIN_' nla_map = ( ('NFTA_CHAIN_UNSPEC', 'none'), ('NFTA_CHAIN_TABLE', 'asciiz'), ('NFTA_CHAIN_HANDLE', 'be64'), ('NFTA_CHAIN_NAME', 'asciiz'), ('NFTA_CHAIN_HOOK', 'hook'), ('NFTA_CHAIN_POLICY', 'be32'), ('NFTA_CHAIN_USE', 'be32'), ('NFTA_CHAIN_TYPE', 'asciiz'), ('NFTA_CHAIN_COUNTERS', 'counters'), ('NFTA_CHAIN_PAD', 'hex'), ('NFTA_CHAIN_FLAGS', 'flags'), ('NFTA_CHAIN_ID', 'be32'), ('NFTA_CHAIN_USERDATA', 'hex'), ) class counters(nla): nla_map = ( ('NFTA_COUNTER_UNSPEC', 'none'), ('NFTA_COUNTER_BYTES', 'be64'), ('NFTA_COUNTER_PACKETS', 'be64'), ) class hook(nft_device): nla_map = ( ('NFTA_HOOK_UNSPEC', 'none'), ('NFTA_HOOK_HOOKNUM', 'be32'), ('NFTA_HOOK_PRIORITY', 'sbe32'), ('NFTA_HOOK_DEV', 'asciiz'), ('NFTA_HOOK_DEVS', 'device_attributes'), ) class flags(nft_flags_be32): ops = ('NFT_CHAIN_HW_OFFLOAD', 'NFT_CHAIN_BINDING') class nat_flags(nla): class nat_range(nft_flags_be32): ops = ( 'NF_NAT_RANGE_MAP_IPS', 'NF_NAT_RANGE_PROTO_SPECIFIED', 'NF_NAT_RANGE_PROTO_RANDOM', 'NF_NAT_RANGE_PERSISTENT', 'NF_NAT_RANGE_PROTO_RANDOM_FULLY', 'NF_NAT_RANGE_PROTO_OFFSET', 'NF_NAT_RANGE_NETMAP', ) class nft_regs(nla): class regs(nft_map_be32): ops = { 0x00: 'NFT_REG_VERDICT', 0x01: 'NFT_REG_1', 0x02: 'NFT_REG_2', 0x03: 'NFT_REG_3', 0x04: 'NFT_REG_4', 0x08: 'NFT_REG32_00', 0x09: 'NFT_REG32_01', 0x0A: 'NFT_REG32_02', 0x0B: 'NFT_REG32_03', 0x0C: 'NFT_REG32_04', 0x0D: 'NFT_REG32_05', 0x0E: 'NFT_REG32_06', 0x0F: 'NFT_REG32_07', 0x10: 'NFT_REG32_08', 0x11: 'NFT_REG32_09', 0x12: 'NFT_REG32_10', 0x13: 'NFT_REG32_11', 0x14: 'NFT_REG32_12', 0x15: 'NFT_REG32_13', 0x16: 'NFT_REG32_14', 0x17: 'NFT_REG32_15', } class nft_data(nla): class nfta_data(nla): nla_map = ( ('NFTA_DATA_UNSPEC', 'none'), ('NFTA_DATA_VALUE', 'cdata'), ('NFTA_DATA_VERDICT', 'verdict'), ) class verdict(nla): nla_map = ( ('NFTA_VERDICT_UNSPEC', 'none'), ('NFTA_VERDICT_CODE', 'verdict_code'), ('NFTA_VERDICT_CHAIN', 'asciiz'), ) class verdict_code(nft_map_be32_signed): ops = { 0: 'NF_DROP', 1: 'NF_ACCEPT', 2: 'NF_STOLEN', 3: 'NF_QUEUE', 4: 'NF_REPEAT', 5: 'NF_STOP', -1: 'NFT_CONTINUE', -2: 'NFT_BREAK', -3: 'NFT_JUMP', -4: 'NFT_GOTO', -5: 'NFT_RETURN', } # nft_expr struct, used for rules and set class nft_contains_expr: class nft_expr(nla): header_type = 1 nla_map = ( ('NFTA_EXPR_UNSPEC', 'none'), ('NFTA_EXPR_NAME', 'asciiz'), ('NFTA_EXPR_DATA', 'expr'), ) class nft_bitwise(nft_data, nft_regs): nla_map = ( ('NFTA_BITWISE_UNSPEC', 'none'), ('NFTA_BITWISE_SREG', 'regs'), ('NFTA_BITWISE_DREG', 'regs'), ('NFTA_BITWISE_LEN', 'be32'), ('NFTA_BITWISE_MASK', 'nfta_data'), ('NFTA_BITWISE_XOR', 'nfta_data'), ('NFTA_BITWISE_OP', 'bitwise_op'), ('NFTA_BITWISE_DATA', 'nfta_data'), ) class bitwise_op(nft_map_be32): ops = { 0: 'NFT_BITWISE_BOOL', 1: 'NFT_BITWISE_LSHIFT', 2: 'NFT_BITWISE_RSHIFT', } class nft_byteorder(nft_regs): nla_map = ( ('NFTA_BYTEORDER_UNSPEC', 'none'), ('NFTA_BYTEORDER_SREG', 'regs'), ('NFTA_BYTEORDER_DREG', 'regs'), ('NFTA_BYTEORDER_OP', 'ops'), ('NFTA_BYTEORDER_LEN', 'be32'), ('NFTA_BYTEORDER_SIZE', 'be32'), ) class ops(nft_map_be32): ops = {0: 'NFT_BYTEORDER_NTOH', 1: 'NFT_BYTEORDER_HTON'} class nft_cmp(nft_data, nft_regs): nla_map = ( ('NFTA_CMP_UNSPEC', 'none'), ('NFTA_CMP_SREG', 'regs'), ('NFTA_CMP_OP', 'ops'), ('NFTA_CMP_DATA', 'nfta_data'), ) class ops(nft_map_be32): ops = { 0: 'NFT_CMP_EQ', 1: 'NFT_CMP_NEQ', 2: 'NFT_CMP_LT', 3: 'NFT_CMP_LTE', 4: 'NFT_CMP_GT', 5: 'NFT_CMP_GTE', } class nft_match(nla): nla_map = ( ('NFTA_MATCH_UNSPEC', 'none'), ('NFTA_MATCH_NAME', 'asciiz'), ('NFTA_MATCH_REV', 'be32'), ('NFTA_MATCH_INFO', 'hex'), ('NFTA_MATCH_PROTOCOL', 'hex'), ('NFTA_MATCH_FLAGS', 'hex'), ) class nft_target(nla): nla_map = ( ('NFTA_TARGET_UNSPEC', 'none'), ('NFTA_TARGET_NAME', 'asciiz'), ('NFTA_TARGET_REV', 'be32'), ('NFTA_TARGET_INFO', 'hex'), ('NFTA_TARGET_PROTOCOL', 'hex'), ('NFTA_TARGET_FLAGS', 'hex'), ) class nft_connlimit(nla): nla_map = ( ('NFTA_CONNLIMIT_UNSPEC', 'none'), ('NFTA_CONNLIMIT_COUNT', 'be32'), ('NFTA_CONNLIMIT_FLAGS', 'connlimit_flags'), ) class connlimit_flags(nft_flags_be32): ops = ('NFT_LIMIT_F_INV',) class nft_counter(nla): nla_map = ( ('NFTA_COUNTER_UNSPEC', 'none'), ('NFTA_COUNTER_BYTES', 'be64'), ('NFTA_COUNTER_PACKETS', 'be64'), ) class nft_ct(nft_regs): nla_map = ( ('NFTA_CT_UNSPEC', 'none'), ('NFTA_CT_DREG', 'regs'), ('NFTA_CT_KEY', 'keys'), ('NFTA_CT_DIRECTION', 'uint8'), ('NFTA_CT_SREG', 'regs'), ) class keys(nft_map_be32): ops = { 0x00: 'NFT_CT_STATE', 0x01: 'NFT_CT_DIRECTION', 0x02: 'NFT_CT_STATUS', 0x03: 'NFT_CT_MARK', 0x04: 'NFT_CT_SECMARK', 0x05: 'NFT_CT_EXPIRATION', 0x06: 'NFT_CT_HELPER', 0x07: 'NFT_CT_L3PROTOCOL', 0x08: 'NFT_CT_SRC', 0x09: 'NFT_CT_DST', 0x0A: 'NFT_CT_PROTOCOL', 0x0B: 'NFT_CT_PROTO_SRC', 0x0C: 'NFT_CT_PROTO_DST', 0x0D: 'NFT_CT_LABELS', 0x0E: 'NFT_CT_PKTS', 0x0F: 'NFT_CT_BYTES', 0x10: 'NFT_CT_AVGPKT', 0x11: 'NFT_CT_ZONE', 0x12: 'NFT_CT_EVENTMASK', 0x13: 'NFT_CT_SRC_IP', 0x14: 'NFT_CT_DST_IP', 0x15: 'NFT_CT_SRC_IP6', 0x16: 'NFT_CT_DST_IP6', 0x17: 'NFT_CT_ID', } class nft_dup(nft_regs): nla_map = ( ('NFTA_DUP_UNSPEC', 'none'), ('NFTA_DUP_SREG_ADDR', 'regs'), ('NFTA_DUP_SREG_DEV', 'regs'), ) class nft_exthdr(nft_regs): nla_map = ( ('NFTA_EXTHDR_UNSPEC', 'none'), ('NFTA_EXTHDR_DREG', 'regs'), ('NFTA_EXTHDR_TYPE', 'uint8'), ('NFTA_EXTHDR_OFFSET', 'be32'), ('NFTA_EXTHDR_LEN', 'be32'), ('NFTA_EXTHDR_FLAGS', 'exthdr_flags'), ('NFTA_EXTHDR_OP', 'exthdr_op'), ('NFTA_EXTHDR_SREG', 'regs'), ) class exthdr_flags(nft_flags_be32): ops = ('NFT_EXTHDR_F_PRESENT',) class exthdr_op(nft_map_be32): ops = { 0: 'NFT_EXTHDR_OP_IPV6', 1: 'NFT_EXTHDR_OP_TCPOPT', 2: 'NFT_EXTHDR_OP_IPV4', } class nft_fib(nft_regs): nla_map = ( ('NFTA_FIB_UNSPEC', 'none'), ('NFTA_FIB_DREG', 'regs'), ('NFTA_FIB_RESULT', 'fib_result'), ('NFTA_FIB_FLAGS', 'fib_flags'), ) class fib_result(nft_flags_be32): ops = ( 'NFT_FIB_RESULT_UNSPEC', 'NFT_FIB_RESULT_OIF', 'NFT_FIB_RESULT_OIFNAME', 'NFT_FIB_RESULT_ADDRTYPE', ) class fib_flags(nft_map_be32): ops = { 0: 'NFTA_FIB_F_SADDR', 1: 'NFTA_FIB_F_DADDR', 2: 'NFTA_FIB_F_MARK', 3: 'NFTA_FIB_F_IIF', 4: 'NFTA_FIB_F_OIF', 5: 'NFTA_FIB_F_PRESENT', } class nft_fwd(nft_regs): nla_map = ( ('NFTA_FWD_UNSPEC', 'none'), ('NFTA_FWD_SREG_DEV', 'regs'), ('NFTA_FWD_SREG_ADDR', 'regs'), ('NFTA_FWD_NFPROTO', 'u32'), ) class nft_hash(nft_regs): nla_map = ( ('NFTA_HASH_UNSPEC', 'none'), ('NFTA_HASH_SREG', 'regs'), ('NFTA_HASH_DREG', 'regs'), ('NFTA_HASH_LEN', 'be32'), ('NFTA_HASH_MODULUS', 'be32'), ('NFTA_HASH_SEED', 'be32'), ('NFTA_HASH_OFFSET', 'be32'), ('NFTA_HASH_TYPE', 'hash_type'), ('NFTA_HASH_SET_NAME', 'asciiz'), ('NFTA_HASH_SET_ID', 'be32'), ) class hash_type(nft_map_be32): ops = {0: 'NFT_HASH_JENKINS', 1: 'NFT_HASH_SYM'} class nft_immediate(nft_data, nft_regs): nla_map = ( ('NFTA_IMMEDIATE_UNSPEC', 'none'), ('NFTA_IMMEDIATE_DREG', 'regs'), ('NFTA_IMMEDIATE_DATA', 'nfta_data'), ) class nft_limit(nla): nla_map = ( ('NFTA_LIMIT_UNSPEC', 'none'), ('NFTA_LIMIT_RATE', 'be64'), ('NFTA_LIMIT_UNIT', 'be64'), ('NFTA_LIMIT_BURST', 'be32'), ('NFTA_LIMIT_TYPE', 'types'), ('NFTA_LIMIT_FLAGS', 'be32'), ) # make flags type class types(nft_map_be32): ops = {0: 'NFT_LIMIT_PKTS', 1: 'NFT_LIMIT_PKT_BYTES'} class nft_log(nla): nla_map = ( ('NFTA_LOG_UNSPEC', 'none'), ('NFTA_LOG_GROUP', 'be32'), ('NFTA_LOG_PREFIX', 'asciiz'), ('NFTA_LOG_SNAPLEN', 'be32'), ('NFTA_LOG_QTHRESHOLD', 'be32'), ('NFTA_LOG_LEVEL', 'log_level'), ('NFTA_LOG_FLAGS', 'log_flags'), ) class log_level(nft_map_be32): ops = { 0: 'NFT_LOGLEVEL_EMERG', 1: 'NFT_LOGLEVEL_ALERT', 2: 'NFT_LOGLEVEL_CRIT', 3: 'NFT_LOGLEVEL_ERR', 4: 'NFT_LOGLEVEL_WARNING', 5: 'NFT_LOGLEVEL_NOTICE', 6: 'NFT_LOGLEVEL_INFO', 7: 'NFT_LOGLEVEL_DEBUG', 8: 'NFT_LOGLEVEL_AUDIT', } class log_flags(nft_flags_be32): ops = ( 'NF_LOG_TCPSEQ', 'NF_LOG_TCPOPT', 'NF_LOG_IPOPT', 'NF_LOG_UID', 'NF_LOG_NFLOG', 'NF_LOG_MACDECODE', ) class nft_lookup(nft_regs): nla_map = ( ('NFTA_LOOKUP_UNSPEC', 'none'), ('NFTA_LOOKUP_SET', 'asciiz'), ('NFTA_LOOKUP_SREG', 'regs'), ('NFTA_LOOKUP_DREG', 'regs'), ('NFTA_LOOKUP_SET_ID', 'be32'), ('NFTA_LOOKUP_FLAGS', 'lookup_flags'), ) class lookup_flags(nft_flags_be32): ops = ('NFT_LOOKUP_F_INV',) class nft_masq(nft_regs, nat_flags): nla_map = ( ('NFTA_MASQ_UNSPEC', 'none'), ('NFTA_MASQ_FLAGS', 'nat_range'), ('NFTA_MASQ_REG_PROTO_MIN', 'regs'), ('NFTA_MASQ_REG_PROTO_MAX', 'regs'), ) class nft_meta(nft_regs): nla_map = ( ('NFTA_META_UNSPEC', 'none'), ('NFTA_META_DREG', 'regs'), ('NFTA_META_KEY', 'meta_key'), ('NFTA_META_SREG', 'regs'), ) class meta_key(nft_map_be32): ops = { 0: 'NFT_META_LEN', 1: 'NFT_META_PROTOCOL', 2: 'NFT_META_PRIORITY', 3: 'NFT_META_MARK', 4: 'NFT_META_IIF', 5: 'NFT_META_OIF', 6: 'NFT_META_IIFNAME', 7: 'NFT_META_OIFNAME', 8: 'NFT_META_IIFTYPE', 9: 'NFT_META_OIFTYPE', 10: 'NFT_META_SKUID', 11: 'NFT_META_SKGID', 12: 'NFT_META_NFTRACE', 13: 'NFT_META_RTCLASSID', 14: 'NFT_META_SECMARK', 15: 'NFT_META_NFPROTO', 16: 'NFT_META_L4PROTO', 17: 'NFT_META_BRI_IIFNAME', 18: 'NFT_META_BRI_OIFNAME', 19: 'NFT_META_PKTTYPE', 20: 'NFT_META_CPU', 21: 'NFT_META_IIFGROUP', 22: 'NFT_META_OIFGROUP', 23: 'NFT_META_CGROUP', 24: 'NFT_META_PRANDOM', 25: 'NFT_META_SECPATH', 26: 'NFT_META_IIFKIND', 27: 'NFT_META_OIFKIND', 28: 'NFT_META_BRI_IIFPVID', 29: 'NFT_META_BRI_IIFVPROTO', 30: 'NFT_META_TIME_NS', 31: 'NFT_META_TIME_DAY', 32: 'NFT_META_TIME_HOUR', 33: 'NFT_META_SDIF', 34: 'NFT_META_SDIFNAME', } class nft_nat(nft_regs, nat_flags): nla_map = ( ('NFTA_NAT_UNSPEC', 'none'), ('NFTA_NAT_TYPE', 'types'), ('NFTA_NAT_FAMILY', 'be32'), ('NFTA_NAT_REG_ADDR_MIN', 'regs'), ('NFTA_NAT_REG_ADDR_MAX', 'regs'), ('NFTA_NAT_REG_PROTO_MIN', 'regs'), ('NFTA_NAT_REG_PROTO_MAX', 'regs'), ('NFTA_NAT_FLAGS', 'nat_range'), ) class types(nft_map_be32): ops = {0: 'NFT_NAT_SNAT', 1: 'NFT_NAT_DNAT'} class nft_numgen(nft_regs): nla_map = ( ('NFTA_NG_UNSPEC', 'none'), ('NFTA_NG_DREG', 'regs'), ('NFTA_NG_MODULUS', 'be32'), ('NFTA_NG_TYPE', 'types'), ('NFTA_NG_OFFSET', 'be32'), ('NFTA_NG_SET_NAME', 'asciiz'), ('NFTA_NG_SET_ID', 'be32'), ) class types(nft_map_be32): ops = {0: 'NFT_NG_INCREMENTAL', 1: 'NFT_NG_RANDOM'} class nft_objref(nft_regs): nla_map = ( ('NFTA_OBJREF_UNSPEC', 'none'), ('NFTA_OBJREF_IMM_TYPE', 'regs'), ('NFTA_OBJREF_IMM_NAME', 'asciiz'), ('NFTA_OBJREF_SET_SREG', 'regs'), ('NFTA_OBJREF_SET_NAME', 'asciiz'), ('NFTA_OBJREF_SET_ID', 'be32'), ) class nft_offload(nla): nla_map = ( ('NFTA_FLOW_UNSPEC', 'none'), ('NFTA_FLOW_TABLE_NAME', 'asciiz'), ) class nft_osf(nft_regs): nla_map = ( ('NFTA_OSF_UNSPEC', 'none'), ('NFTA_OSF_DREG', 'regs'), ('NFTA_OSF_TTL', 'uint8'), ('NFTA_OSF_FLAGS', 'osf_flags'), ) class osf_flags(nft_flags_be32): ops = ('NFT_OSF_F_VERSION',) class nft_payload(nft_regs): nla_map = ( ('NFTA_PAYLOAD_UNSPEC', 'none'), ('NFTA_PAYLOAD_DREG', 'regs'), ('NFTA_PAYLOAD_BASE', 'base_type'), ('NFTA_PAYLOAD_OFFSET', 'be32'), ('NFTA_PAYLOAD_LEN', 'be32'), ('NFTA_PAYLOAD_SREG', 'regs'), ('NFTA_PAYLOAD_CSUM_TYPE', 'csum_type'), ('NFTA_PAYLOAD_CSUM_OFFSET', 'be32'), ('NFTA_PAYLOAD_CSUM_FLAGS', 'csum_flags'), ) class base_type(nft_map_be32): ops = { 0: 'NFT_PAYLOAD_LL_HEADER', 1: 'NFT_PAYLOAD_NETWORK_HEADER', 2: 'NFT_PAYLOAD_TRANSPORT_HEADER', } class csum_type(nft_map_be32): ops = { 0: 'NFT_PAYLOAD_CSUM_NONE', 1: 'NFT_PAYLOAD_CSUM_INET', # RFC 791 2: 'NFT_PAYLOAD_CSUM_SCTP', } # RFC 3309 class csum_flags(nft_flags_be32): ops = ('NFT_PAYLOAD_L4CSUM_PSEUDOHDR',) class nft_queue(nft_regs): nla_map = ( ('NFTA_QUEUE_UNSPEC', 'none'), ('NFTA_QUEUE_NUM', 'be16'), ('NFTA_QUEUE_TOTAL', 'be16'), ('NFTA_QUEUE_FLAGS', 'queue_flags'), ('NFTA_QUEUE_SREG_QNUM', 'regs'), ) class queue_flags(nft_flags_be16): ops = ('NFT_QUEUE_FLAG_BYPASS', 'NFT_QUEUE_FLAG_CPU_FANOUT') class nft_quota(nla): nla_map = ( ('NFTA_QUOTA_UNSPEC', 'none'), ('NFTA_QUOTA_BYTES', 'be16'), ('NFTA_QUOTA_FLAGS', 'quota_flags'), ('NFTA_QUOTA_PAD', 'hex'), ('NFTA_QUOTA_CONSUMED', 'be64'), ) class quota_flags(nft_flags_be32): ops = ('NFT_QUOTA_F_INV', 'NFT_QUOTA_F_DEPLETED') class nft_range(nft_regs, nft_data): nla_map = ( ('NFTA_RANGE_UNSPEC', 'none'), ('NFTA_RANGE_SREG', 'regs'), ('NFTA_RANGE_OP', 'range_op'), ('NFTA_RANGE_FROM_DATA', 'nfta_data'), ('NFTA_RANGE_TO_DATA', 'nfta_data'), ) class range_op(nft_map_be32): ops = {0: 'NFT_RANGE_EQ', 1: 'NFT_RANGE_NEQ'} class nft_redir(nft_regs, nat_flags): nla_map = ( ('NFTA_REDIR_UNSPEC', 'none'), ('NFTA_REDIR_REG_PROTO_MIN', 'regs'), ('NFTA_REDIR_REG_PROTO_MAX', 'regs'), ('NFTA_REDIR_FLAGS', 'nat_range'), ) class nft_reject(nla): nla_map = ( ('NFTA_REJECT_UNSPEC', 'none'), ('NFTA_REJECT_TYPE', 'types'), ('NFTA_REJECT_ICMP_CODE', 'codes'), ) class types(nft_map_be32): ops = { 0: 'NFT_REJECT_ICMP_UNREACH', 1: 'NFT_REJECT_TCP_RST', 2: 'NFT_REJECT_ICMPX_UNREACH', } class codes(nft_map_uint8): ops = { 0: 'NFT_REJECT_ICMPX_NO_ROUTE', 1: 'NFT_REJECT_ICMPX_PORT_UNREACH', 2: 'NFT_REJECT_ICMPX_HOST_UNREACH', 3: 'NFT_REJECT_ICMPX_ADMIN_PROHIBITED', } class nft_rt(nft_regs): nla_map = ( ('NFTA_RT_UNSPEC', 'none'), ('NFTA_RT_DREG', 'regs'), ('NFTA_RT_KEY', 'rt_keys'), ) class rt_keys(nft_map_be32): ops = { 0: 'NFT_RT_CLASSID', 1: 'NFT_RT_NEXTHOP4', 2: 'NFT_RT_NEXTHOP6', 3: 'NFT_RT_TCPMSS', 4: 'NFT_RT_XFRM', } class nft_secmark(nla): nla_map = ( ('NFTA_SECMARK_UNSPEC', 'none'), ('NFTA_SECMARK_CTX', 'asciiz'), ) class nft_socket(nft_regs): nla_map = ( ('NFTA_SOCKET_UNSPEC', 'none'), ('NFTA_SOCKET_KEY', 'socket_keys'), ('NFTA_SOCKET_DREG', 'regs'), ) class socket_keys(nft_map_be32): ops = { 0: 'NFT_SOCKET_TRANSPARENT', 1: 'NFT_SOCKET_MARK', 2: 'NFT_SOCKET_WILDCARD', } class nft_synproxy(nla): nla_map = ( ('NFTA_SYNPROXY_UNSPEC', 'none'), ('NFTA_SYNPROXY_MSS', 'u16'), ('NFTA_SYNPROXY_WSCALE', 'uint8'), ('NFTA_SYNPROXY_FLAGS', 'synproxy_flags'), ) class synproxy_flags(nft_flags_be32): ops = ( 'NF_SYNPROXY_OPT_MSS', 'NF_SYNPROXY_OPT_WSCALE', 'NF_SYNPROXY_OPT_SACK_PERM', 'NF_SYNPROXY_OPT_TIMESTAMP', 'NF_SYNPROXY_OPT_ECN', ) class nft_tproxy(nft_regs): nla_map = ( ('NFTA_TPROXY_UNSPEC', 'none'), ('NFTA_TPROXY_FAMILY', 'regs'), ('NFTA_TPROXY_REG_ADDR', 'regs'), ('NFTA_TPROXY_REG_PORT', 'regs'), ) class nft_dynset(nft_regs): rule_expr = None nla_map = ( ('NFTA_DYNSET_UNSPEC', 'none'), ('NFTA_DYNSET_SET_NAME', 'asciiz'), ('NFTA_DYNSET_SET_ID', 'be32'), ('NFTA_DYNSET_OP', 'dynset_op'), ('NFTA_DYNSET_SREG_KEY', 'regs'), ('NFTA_DYNSET_SREG_DATA', 'regs'), ('NFTA_DYNSET_TIMEOUT', 'be64'), ('NFTA_DYNSET_EXPR', 'rule_expr'), ('NFTA_DYNSET_PAD', 'hex'), ('NFTA_DYNSET_FLAGS', 'dynset_flags'), ) class dynset_flags(nft_flags_be32): ops = ('NFT_DYNSET_F_INV',) class dynset_op(nft_map_be32): ops = { 0: 'NFT_DYNSET_OP_ADD', 1: 'NFT_DYNSET_OP_UPDATE', 2: 'NFT_DYNSET_OP_DELETE', } class nft_xfrm(nft_regs): nla_map = ( ('NFTA_XFRM_UNSPEC', 'none'), ('NFTA_XFRM_DREG', 'regs'), ('NFTA_XFRM_KEY', 'xfrm_key'), ('NFTA_XFRM_DIR', 'uint8'), ('NFTA_XFRM_SPNUM', 'be32'), ) class xfrm_key(nft_map_be32): ops = { 0: 'NFT_XFRM_KEY_UNSPEC', 1: 'NFT_XFRM_KEY_DADDR_IP4', 2: 'NFT_XFRM_KEY_DADDR_IP6', 3: 'NFT_XFRM_KEY_SADDR_IP4', 4: 'NFT_XFRM_KEY_SADDR_IP6', 5: 'NFT_XFRM_KEY_REQID', 6: 'NFT_XFRM_KEY_SPI', } @staticmethod def expr(self, *argv, **kwarg): data_type = self.get_attr('NFTA_EXPR_NAME') expr = getattr(self, 'nft_%s' % data_type, self.hex) if hasattr(expr, 'rule_expr'): expr.rule_expr = self.__class__ return expr class nft_rule_msg(nfgen_msg, nft_contains_expr): prefix = 'NFTA_RULE_' nla_map = ( ('NFTA_RULE_UNSPEC', 'none'), ('NFTA_RULE_TABLE', 'asciiz'), ('NFTA_RULE_CHAIN', 'asciiz'), ('NFTA_RULE_HANDLE', 'be64'), ('NFTA_RULE_EXPRESSIONS', '*nft_expr'), ('NFTA_RULE_COMPAT', 'hex'), ('NFTA_RULE_POSITION', 'be64'), ('NFTA_RULE_USERDATA', 'hex'), ('NFTA_RULE_PAD', 'hex'), ('NFTA_RULE_ID', 'be32'), ('NFTA_RULE_POSITION_ID', 'be32'), ('NFTA_RULE_CHAIN_ID', 'be32'), ) class nft_set_msg(nfgen_msg, nft_contains_expr): prefix = 'NFTA_SET_' nla_map = ( ('NFTA_SET_UNSPEC', 'none'), ('NFTA_SET_TABLE', 'asciiz'), ('NFTA_SET_NAME', 'asciiz'), ('NFTA_SET_FLAGS', 'set_flags'), ('NFTA_SET_KEY_TYPE', 'be32'), ('NFTA_SET_KEY_LEN', 'be32'), ('NFTA_SET_DATA_TYPE', 'be32'), ('NFTA_SET_DATA_LEN', 'be32'), ('NFTA_SET_POLICY', 'set_policy'), ('NFTA_SET_DESC', 'set_desc'), ('NFTA_SET_ID', 'be32'), ('NFTA_SET_TIMEOUT', 'be64'), ('NFTA_SET_GC_INTERVAL', 'be32'), ('NFTA_SET_USERDATA', 'set_udata'), ('NFTA_SET_PAD', 'hex'), ('NFTA_SET_OBJ_TYPE', 'be32'), ('NFTA_SET_HANDLE', 'be64'), ('NFTA_SET_EXPR', 'nft_expr'), ('NFTA_SET_EXPRESSIONS', '*nft_expr'), ) class set_udata(nftnl_udata): udata_types = ( "NFTNL_UDATA_SET_KEYBYTEORDER", "NFTNL_UDATA_SET_DATABYTEORDER", "NFTNL_UDATA_SET_MERGE_ELEMENTS", "NFTNL_UDATA_SET_KEY_TYPEOF", "NFTNL_UDATA_SET_DATA_TYPEOF", "NFTNL_UDATA_SET_EXPR", "NFTNL_UDATA_SET_DATA_INTERVAL", "NFTNL_UDATA_SET_COMMENT", ) class set_flags(nft_flags_be32): ops = ( 'NFT_SET_ANONYMOUS', 'NFT_SET_CONSTANT', 'NFT_SET_INTERVAL', 'NFT_SET_MAP', 'NFT_SET_TIMEOUT', 'NFT_SET_EVAL', 'NFT_SET_OBJECT', 'NFT_SET_CONCAT', ) class set_policy(nft_map_be32): ops = {0: 'NFT_SET_POL_PERFORMANCE', 1: 'NFT_SET_POL_MEMORY'} class set_desc(nla): nla_map = ( ('NFTA_SET_DESC_UNSPEC', 'none'), ('NFTA_SET_DESC_SIZE', 'be32'), ('NFTA_SET_DESC_CONCAT', '*list_elem'), ) class list_elem(nla): nla_map = ( ('NFTA_LIST_UNSPEC', 'none'), ('NFTA_LIST_ELEM', '*set_field_attribute'), ) class set_field_attribute(nla): nla_map = ( ('NFTA_SET_FIELD_UNSPEC', 'none'), ('NFTA_SET_FIELD_LEN', 'be32'), ) class nft_table_msg(nfgen_msg, nft_contains_expr): prefix = 'NFTA_TABLE_' nla_map = ( ('NFTA_TABLE_UNSPEC', 'none'), ('NFTA_TABLE_NAME', 'asciiz'), ('NFTA_TABLE_FLAGS', 'be32'), ('NFTA_TABLE_USE', 'be32'), ('NFTA_TABLE_HANDLE', 'be64'), ('NFTA_TABLE_PAD', 'hex'), ('NFTA_TABLE_USERDATA', 'hex'), ) class nft_set_elem_list_msg(nfgen_msg): prefix = 'NFTA_SET_ELEM_LIST_' nla_map = ( ('NFTA_SET_ELEM_LIST_UNSPEC', 'none'), ('NFTA_SET_ELEM_LIST_TABLE', 'asciiz'), ('NFTA_SET_ELEM_LIST_SET', 'asciiz'), ('NFTA_SET_ELEM_LIST_ELEMENTS', '*set_elem'), ('NFTA_SET_ELEM_LIST_SET_ID', 'be32'), ) class set_elem(nla, nft_contains_expr): nla_map = ( ('NFTA_SET_ELEM_UNSPEC', 'none'), ('NFTA_SET_ELEM_KEY', 'data_attributes'), ('NFTA_SET_ELEM_DATA', 'data_attributes'), ('NFTA_SET_ELEM_FLAGS', 'set_elem_flags'), ('NFTA_SET_ELEM_TIMEOUT', 'be64'), ('NFTA_SET_ELEM_EXPIRATION', 'be64'), ('NFTA_SET_ELEM_USERDATA', 'set_elem_udata'), ('NFTA_SET_ELEM_EXPR', 'nft_expr'), ('NFTA_SET_ELEM_PAD', 'hex'), ('NFTA_SET_ELEM_OBJREF', 'asciiz'), ('NFTA_SET_ELEM_KEY_END', 'data_attributes'), ('NFTA_SET_ELEM_EXPRESSIONS', '*nft_expr'), ) class set_elem_udata(nftnl_udata): udata_types = ( "NFTNL_UDATA_SET_ELEM_COMMENT", "NFTNL_UDATA_SET_ELEM_FLAGS", ) class set_elem_flags(nft_flags_be32): ops = {1: 'NFT_SET_ELEM_INTERVAL_END'} class data_attributes(nla): nla_map = ( ('NFTA_DATA_UNSPEC', 'none'), ('NFTA_DATA_VALUE', 'binary'), ('NFTA_DATA_VERDICT', 'verdict_attributes'), ) class verdict_attributes(nla): nla_map = ( ('NFTA_VERDICT_UNSPEC', 'none'), ('NFTA_VERDICT_CODE', 'verdict_code'), ('NFTA_VERDICT_CHAIN', 'asciiz'), ('NFTA_VERDICT_CHAIN_ID', 'be32'), ) class verdict_code(nft_map_be32_signed): ops = { 0: 'NF_DROP', 1: 'NF_ACCEPT', 2: 'NF_STOLEN', 3: 'NF_QUEUE', 4: 'NF_REPEAT', 5: 'NF_STOP', -1: 'NFT_CONTINUE', -2: 'NFT_BREAK', -3: 'NFT_JUMP', -4: 'NFT_GOTO', -5: 'NFT_RETURN', } class nft_flowtable_msg(nfgen_msg): prefix = 'NFTA_FLOWTABLE_' nla_map = ( ('NFTA_FLOWTABLE_UNSPEC', 'none'), ('NFTA_FLOWTABLE_TABLE', 'asciiz'), ('NFTA_FLOWTABLE_NAME', 'asciiz'), ('NFTA_FLOWTABLE_HOOK', 'flowtable_hook'), ('NFTA_FLOWTABLE_USE', 'be32'), ('NFTA_FLOWTABLE_HANDLE', 'be64'), ('NFTA_FLOWTABLE_PAD', 'hex'), ('NFTA_FLOWTABLE_FLAGS', 'nft_flowtable_flags'), ) class nft_flowtable_flags(nft_flags_be32): ops = ('NFT_FLOWTABLE_HW_OFFLOAD', 'NFT_FLOWTABLE_COUNTER') class flowtable_hook(nft_device): nla_map = ( ('NFTA_FLOWTABLE_HOOK_UNSPEC', 'none'), ('NFTA_FLOWTABLE_HOOK_NUM', 'be32'), ('NFTA_FLOWTABLE_HOOK_PRIORITY', 'be32'), ('NFTA_FLOWTABLE_HOOK_DEVS', 'device_attributes'), ) class NFTSocket(NetlinkSocket): ''' NFNetlink socket (family=NETLINK_NETFILTER). Implements API to the nftables functionality. ''' policy = { NFT_MSG_NEWTABLE: nft_table_msg, NFT_MSG_GETTABLE: nft_table_msg, NFT_MSG_DELTABLE: nft_table_msg, NFT_MSG_NEWCHAIN: nft_chain_msg, NFT_MSG_GETCHAIN: nft_chain_msg, NFT_MSG_DELCHAIN: nft_chain_msg, NFT_MSG_NEWRULE: nft_rule_msg, NFT_MSG_GETRULE: nft_rule_msg, NFT_MSG_DELRULE: nft_rule_msg, NFT_MSG_NEWSET: nft_set_msg, NFT_MSG_GETSET: nft_set_msg, NFT_MSG_DELSET: nft_set_msg, NFT_MSG_NEWGEN: nft_gen_msg, NFT_MSG_GETGEN: nft_gen_msg, NFT_MSG_NEWSETELEM: nft_set_elem_list_msg, NFT_MSG_GETSETELEM: nft_set_elem_list_msg, NFT_MSG_DELSETELEM: nft_set_elem_list_msg, NFT_MSG_NEWFLOWTABLE: nft_flowtable_msg, NFT_MSG_GETFLOWTABLE: nft_flowtable_msg, NFT_MSG_DELFLOWTABLE: nft_flowtable_msg, } def __init__(self, version=1, attr_revision=0, nfgen_family=2): super(NFTSocket, self).__init__(family=NETLINK_NETFILTER) policy = dict( [ (x | (NFNL_SUBSYS_NFTABLES << 8), y) for (x, y) in self.policy.items() ] ) self.register_policy(policy) self._proto_version = version self._attr_revision = attr_revision self._nfgen_family = nfgen_family self._ts = threading.local() self._write_lock = threading.RLock() def begin(self): with self._write_lock: if hasattr(self._ts, 'data'): # transaction is already started return False self._ts.data = b'' self._ts.seqnum = ( self.addr_pool.alloc(), # begin self.addr_pool.alloc(), # tx self.addr_pool.alloc(), ) # commit msg = nfgen_msg() msg['res_id'] = NFNL_SUBSYS_NFTABLES msg['header']['type'] = 0x10 msg['header']['flags'] = NLM_F_REQUEST msg['header']['sequence_number'] = self._ts.seqnum[0] msg.encode() self._ts.data += msg.data return True def commit(self): with self._write_lock: msg = nfgen_msg() msg['res_id'] = NFNL_SUBSYS_NFTABLES msg['header']['type'] = 0x11 msg['header']['flags'] = NLM_F_REQUEST msg['header']['sequence_number'] = self._ts.seqnum[2] msg.encode() self._ts.data += msg.data self.sendto(self._ts.data, (0, 0)) for seqnum in self._ts.seqnum: self.addr_pool.free(seqnum, ban=10) del self._ts.data def request_get( self, msg, msg_type, msg_flags=NLM_F_REQUEST | NLM_F_DUMP, terminate=None, ): ''' Read-only requests do not require transactions. Just run the request and get an answer. ''' msg['nfgen_family'] = self._nfgen_family return tuple( self.nlm_request( msg, msg_type | (NFNL_SUBSYS_NFTABLES << 8), msg_flags, terminate=terminate, ) ) def request_put(self, msg, msg_type, msg_flags=NLM_F_REQUEST): ''' Read-write requests. ''' one_shot = self.begin() msg['header']['type'] = (NFNL_SUBSYS_NFTABLES << 8) | msg_type msg['header']['flags'] = msg_flags msg['header']['sequence_number'] = self._ts.seqnum[1] msg['nfgen_family'] = self._nfgen_family msg.encode() self._ts.data += msg.data if one_shot: self.commit() def _command(self, msg_class, commands, cmd, kwarg): flags = kwarg.pop('flags', NLM_F_ACK) cmd_name = cmd cmd_flags = { 'add': NLM_F_CREATE | NLM_F_APPEND, 'create': NLM_F_CREATE | NLM_F_APPEND | NLM_F_EXCL, 'insert': NLM_F_CREATE, 'replace': NLM_F_REPLACE, } flags |= cmd_flags.get(cmd, 0) flags |= NLM_F_REQUEST cmd = commands[cmd] msg = msg_class() msg['attrs'] = [] # # a trick to pass keyword arguments as On rderedDict instance: # # ordered_args = OrderedDict() # ordered_args['arg1'] = value1 # ordered_args['arg2'] = value2 # ... # nft.rule('add', kwarg=ordered_args) # if 'kwarg' in kwarg: kwarg = kwarg['kwarg'] # for key, value in kwarg.items(): nla = msg_class.name2nla(key) msg['attrs'].append([nla, value]) msg['header']['type'] = (NFNL_SUBSYS_NFTABLES << 8) | cmd msg['header']['flags'] = flags | NLM_F_REQUEST msg['nfgen_family'] = self._nfgen_family if cmd_name != 'get': trans_start = nfgen_msg() trans_start['res_id'] = NFNL_SUBSYS_NFTABLES trans_start['header']['type'] = 0x10 trans_start['header']['flags'] = NLM_F_REQUEST trans_end = nfgen_msg() trans_end['res_id'] = NFNL_SUBSYS_NFTABLES trans_end['header']['type'] = 0x11 trans_end['header']['flags'] = NLM_F_REQUEST messages = [trans_start, msg, trans_end] self.nlm_request_batch(messages, noraise=(flags & NLM_F_ACK) == 0) # Only throw an error when the request fails. For now, # do not return anything. else: return self.request_get(msg, msg['header']['type'], flags)[0] # call nft describe "data_type" for more informations DATA_TYPE_NAME_TO_INFO = { "verdict": (DATA_TYPE_VERDICT, 4, nft_data.nfta_data.verdict.verdict_code), "nf_proto": (DATA_TYPE_NFPROTO, 1, nlmsg_atoms.uint8), "bitmask": (DATA_TYPE_BITMASK, 4, nlmsg_atoms.uint32), "integer": (DATA_TYPE_INTEGER, 4, nlmsg_atoms.int32), "string": (DATA_TYPE_STRING, 0, nlmsg_atoms.asciiz), "lladdr": (DATA_TYPE_LLADDR, 0, nlmsg_atoms.lladdr), "ipv4_addr": (DATA_TYPE_IPADDR, 4, nlmsg_atoms.ip4addr), "ipv6_addr": (DATA_TYPE_IP6ADDR, 16, nlmsg_atoms.ip6addr), "ether_addr": (DATA_TYPE_ETHERADDR, 6, nlmsg_atoms.l2addr), "ether_type": (DATA_TYPE_ETHERADDR, 2, nlmsg_atoms.uint16), "inet_proto": (DATA_TYPE_INET_PROTOCOL, 1, nlmsg_atoms.uint8), } DATA_TYPE_ID_TO_NAME = { value[0]: key for key, value in DATA_TYPE_NAME_TO_INFO.items() }