Lines Matching full:self
103 def __init__(self, nl_msg):
104 self.nl_msg = nl_msg
105 self.error = -nl_msg.error
107 def __str__(self):
108 return f"Netlink error: {os.strerror(self.error)}\n{self.nl_msg}"
128 def __init__(self, raw, offset):
129 self._len, self._type = struct.unpack("HH", raw[offset : offset + 4])
130 self.type = self._type & ~Netlink.NLA_TYPE_MASK
131 self.is_nest = self._type & Netlink.NLA_F_NESTED
132 self.payload_len = self._len
133 self.full_len = (self.payload_len + 3) & ~3
134 self.raw = raw[offset + 4 : offset + self.payload_len]
144 def as_scalar(self, attr_type, byte_order=None):
145 format = self.get_format(attr_type, byte_order)
146 return format.unpack(self.raw)[0]
148 def as_auto_scalar(self, attr_type, byte_order=None):
149 if len(self.raw) != 4 and len(self.raw) != 8:
150 raise Exception(f"Auto-scalar len payload be 4 or 8 bytes, got {len(self.raw)}")
151 real_type = attr_type[0] + str(len(self.raw) * 8)
152 format = self.get_format(real_type, byte_order)
153 return format.unpack(self.raw)[0]
155 def as_strz(self):
156 return self.raw.decode('ascii')[:-1]
158 def as_bin(self):
159 return self.raw
161 def as_c_array(self, type):
162 format = self.get_format(type)
163 return [ x[0] for x in format.iter_unpack(self.raw) ]
165 def __repr__(self):
166 return f"[type:{self.type} len:{self._len}] {self.raw}"
170 def __init__(self, msg, offset=0):
171 self.attrs = []
176 self.attrs.append(attr)
178 def __iter__(self):
179 yield from self.attrs
181 def __repr__(self):
183 for a in self.attrs:
191 def __init__(self, msg, offset, attr_space=None):
192 self.hdr = msg[offset : offset + 16]
194 self.nl_len, self.nl_type, self.nl_flags, self.nl_seq, self.nl_portid = \
195 struct.unpack("IHHII", self.hdr)
197 self.raw = msg[offset + 16 : offset + self.nl_len]
199 self.error = 0
200 self.done = 0
203 if self.nl_type == Netlink.NLMSG_ERROR:
204 self.error = struct.unpack("i", self.raw[0:4])[0]
205 self.done = 1
207 elif self.nl_type == Netlink.NLMSG_DONE:
208 self.error = struct.unpack("i", self.raw[0:4])[0]
209 self.done = 1
212 self.extack = None
213 if self.nl_flags & Netlink.NLM_F_ACK_TLVS and extack_off:
214 self.extack = dict()
215 extack_attrs = NlAttrs(self.raw[extack_off:])
218 self.extack['msg'] = extack.as_strz()
220 self.extack['miss-type'] = extack.as_scalar('u32')
222 self.extack['miss-nest'] = extack.as_scalar('u32')
224 self.extack['bad-attr-offs'] = extack.as_scalar('u32')
226 self.extack['policy'] = self._decode_policy(extack.raw)
228 if 'unknown' not in self.extack:
229 self.extack['unknown'] = []
230 self.extack['unknown'].append(extack)
233 self.annotate_extack(attr_space)
235 def _decode_policy(self, raw):
259 def annotate_extack(self, attr_space):
263 if 'miss-type' in self.extack and 'miss-nest' not in self.extack:
264 miss_type = self.extack['miss-type']
267 self.extack['miss-type'] = spec['name']
269 self.extack['miss-type-doc'] = spec['doc']
271 def cmd(self):
272 return self.nl_type
274 def __repr__(self):
275 msg = f"nl_len = {self.nl_len} ({len(self.raw)}) nl_flags = 0x{self.nl_flags:x} nl_type = {self.nl_type}"
276 if self.error:
277 msg += '\n\terror: ' + str(self.error)
278 if self.extack:
279 msg += '\n\textack: ' + repr(self.extack)
284 def __init__(self, data):
285 self.msgs = []
291 self.msgs.append(msg)
293 def __iter__(self):
294 yield from self.msgs
363 def __init__(self, nl_msg):
364 self.nl = nl_msg
365 self.genl_cmd, self.genl_version, _ = struct.unpack_from("BBH", nl_msg.raw, 0)
366 self.raw = nl_msg.raw[4:]
368 def cmd(self):
369 return self.genl_cmd
371 def __repr__(self):
372 msg = repr(self.nl)
373 msg += f"\tgenl_cmd = {self.genl_cmd} genl_ver = {self.genl_version}\n"
374 for a in self.raw_attrs:
380 def __init__(self, family_name, proto_num):
381 self.family_name = family_name
382 self.proto_num = proto_num
384 def _message(self, nl_type, nl_flags, seq=None):
390 def message(self, flags, command, version, seq=None):
391 return self._message(command, flags, seq)
393 def _decode(self, nl_msg):
396 def decode(self, ynl, nl_msg, op):
397 msg = self._decode(nl_msg)
404 def get_mcast_id(self, mcast_name, mcast_groups):
409 def msghdr_size(self):
414 def __init__(self, family_name):
421 self.genl_family = genl_family_name_to_id[family_name]
422 self.family_id = genl_family_name_to_id[family_name]['id']
424 def message(self, flags, command, version, seq=None):
425 nlmsg = self._message(self.family_id, flags, seq)
429 def _decode(self, nl_msg):
432 def get_mcast_id(self, mcast_name, mcast_groups):
433 if mcast_name not in self.genl_family['mcast']:
435 return self.genl_family['mcast'][mcast_name]
437 def msghdr_size(self):
444 def __init__(self, attr_space, attrs, outer = None):
446 inner_scope = self.SpecValuesPair(attr_space, attrs)
447 self.scopes = [inner_scope] + outer_scopes
449 def lookup(self, name):
450 for scope in self.scopes:
466 def __init__(self, def_path, schema=None, process_unknown=False,
470 self.include_raw = False
471 self.process_unknown = process_unknown
474 if self.proto == "netlink-raw":
475 self.nlproto = NetlinkProtocol(self.yaml['name'],
476 self.yaml['protonum'])
478 self.nlproto = GenlProtocol(self.yaml['name'])
480 raise Exception(f"Family '{self.yaml['name']}' not supported by the kernel")
482 self._recv_dbg = False
486 self._recv_size = recv_size if recv_size else 131072
490 if self._recv_size < 4000:
493 self.sock = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, self.nlproto.proto_num)
494 self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_CAP_ACK, 1)
495 self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_EXT_ACK, 1)
496 self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_GET_STRICT_CHK, 1)
498 self.async_msg_ids = set()
499 self.async_msg_queue = queue.Queue()
501 for msg in self.msgs.values():
503 self.async_msg_ids.add(msg.rsp_value)
505 for op_name, op in self.ops.items():
506 bound_f = functools.partial(self._op, op_name)
507 setattr(self, op.ident_name, bound_f)
510 def ntf_subscribe(self, mcast_name):
511 mcast_id = self.nlproto.get_mcast_id(mcast_name, self.mcast_groups)
512 self.sock.bind((0, 0))
513 self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_ADD_MEMBERSHIP,
516 def set_recv_dbg(self, enabled):
517 self._recv_dbg = enabled
519 def _recv_dbg_print(self, reply, nl_msgs):
520 if not self._recv_dbg:
527 def _encode_enum(self, attr_spec, value):
528 enum = self.consts[attr_spec['enum']]
539 def _get_scalar(self, attr_spec, value):
544 return self._encode_enum(attr_spec, value)
546 return self._from_string(value, attr_spec)
549 def _add_attr(self, space, name, value, search_attrs):
551 attr = self.attr_sets[space][name]
559 attr_payload += self._add_attr(space, name, subvalue, search_attrs)
565 attr_payload = self._add_nest_attrs(value, sub_space, search_attrs)
569 attr_payload = self._encode_indexed_array(value, sub_space,
585 attr_payload = self._from_string(value, attr)
589 attr_payload = self._encode_struct(attr.struct_name, value)
596 scalar = self._get_scalar(attr, value)
604 scalar_value = self._get_scalar(attr, value["value"])
605 scalar_selector = self._get_scalar(attr, value["selector"])
608 msg_format, _ = self._resolve_selector(attr, search_attrs)
611 attr_payload += self._encode_struct(msg_format.fixed_header, value)
613 if msg_format.attr_set in self.attr_sets:
617 attr_payload += self._add_attr(msg_format.attr_set,
624 return self._add_attr_raw(nl_type, attr_payload)
626 def _add_attr_raw(self, nl_type, attr_payload):
630 def _add_nest_attrs(self, value, sub_space, search_attrs):
631 sub_attrs = SpaceAttrs(self.attr_sets[sub_space], value, search_attrs)
634 attr_payload += self._add_attr(sub_space, subname, subvalue,
638 def _encode_indexed_array(self, vals, sub_space, search_attrs):
642 val_payload = self._add_nest_attrs(val, sub_space, search_attrs)
643 attr_payload += self._add_attr_raw(idx, val_payload)
646 def _get_enum_or_unknown(self, enum, raw):
650 if self.process_unknown:
656 def _decode_enum(self, raw, attr_spec):
657 enum = self.consts[attr_spec['enum']]
663 value.add(self._get_enum_or_unknown(enum, i))
667 value = self._get_enum_or_unknown(enum, raw)
670 def _decode_binary(self, attr, attr_spec):
672 decoded = self._decode_struct(attr.raw, attr_spec.struct_name)
676 decoded = [ self._decode_enum(x, attr_spec) for x in decoded ]
678 decoded = [ self._formatted_string(x, attr_spec.display_hint)
683 decoded = self._formatted_string(decoded, attr_spec.display_hint)
686 def _decode_array_attr(self, attr, attr_spec):
694 subattrs = self._decode(NlAttrs(item.raw), attr_spec['nested-attributes'])
699 subattr = self._formatted_string(subattr, attr_spec.display_hint)
704 subattr = self._decode_enum(subattr, attr_spec)
706 subattr = self._formatted_string(subattr, attr_spec.display_hint)
712 def _decode_nest_type_value(self, attr, attr_spec):
718 subattrs = self._decode(NlAttrs(value.raw), attr_spec['nested-attributes'])
722 def _decode_unknown(self, attr):
724 return self._decode(NlAttrs(attr.raw), None)
728 def _rsp_add(self, rsp, name, is_multi, decoded):
743 def _resolve_selector(self, attr_spec, search_attrs):
745 if sub_msg not in self.sub_msgs:
747 sub_msg_spec = self.sub_msgs[sub_msg]
757 def _decode_sub_msg(self, attr, attr_spec, search_attrs):
758 msg_format, _ = self._resolve_selector(attr_spec, search_attrs)
762 decoded.update(self._decode_struct(attr.raw, msg_format.fixed_header))
763 offset = self._struct_size(msg_format.fixed_header)
765 if msg_format.attr_set in self.attr_sets:
766 subdict = self._decode(NlAttrs(attr.raw, offset), msg_format.attr_set)
772 def _decode(self, attrs, space, outer_attrs = None):
775 attr_space = self.attr_sets[space]
782 if not self.process_unknown:
785 self._rsp_add(rsp, attr_name, None, self._decode_unknown(attr))
790 subdict = self._decode(NlAttrs(attr.raw), attr_spec['nested-attributes'], search_attrs)
795 decoded = self._decode_binary(attr, attr_spec)
801 decoded = self._decode_enum(decoded, attr_spec)
805 decoded = self._decode_enum(decoded, attr_spec)
807 decoded = self._formatted_string(decoded, attr_spec.display_hint)
809 decoded = self._decode_array_attr(attr, attr_spec)
813 value = self._decode_enum(value, attr_spec)
814 selector = self._decode_enum(selector, attr_spec)
817 decoded = self._decode_sub_msg(attr, attr_spec, search_attrs)
819 decoded = self._decode_nest_type_value(attr, attr_spec)
821 if not self.process_unknown:
823 decoded = self._decode_unknown(attr)
825 self._rsp_add(rsp, attr_spec["name"], attr_spec.is_multi, decoded)
832 def _decode_extack_path(self, attrs, attr_set, offset, target, search_attrs):
849 sub_attrs = self.attr_sets[attr_spec['nested-attributes']]
852 msg_format, value = self._resolve_selector(attr_spec, search_attrs)
855 sub_attrs = self.attr_sets[msg_format.attr_set]
860 subpath = self._decode_extack_path(NlAttrs(attr.raw), sub_attrs,
868 def _decode_extack(self, request, op, extack, vals):
872 msg = self.nlproto.decode(self, NlMsg(request, 0, op.attr_set), op)
873 offset = self.nlproto.msghdr_size() + self._struct_size(op.fixed_header)
875 path = self._decode_extack_path(msg.raw_attrs, op.attr_set, offset,
881 def _struct_size(self, name):
883 members = self.consts[name].members
888 size += self._struct_size(m.struct)
898 def _decode_struct(self, data, name):
899 members = self.consts[name].members
908 len = self._struct_size(m.struct)
909 value = self._decode_struct(data[offset : offset + len],
921 value = self._decode_enum(value, m)
923 value = self._formatted_string(value, m.display_hint)
927 def _encode_struct(self, name, vals):
928 members = self.consts[name].members
938 attr_payload += self._encode_struct(m.struct, value)
951 def _formatted_string(self, raw, display_hint):
967 def _from_string(self, string, attr_spec):
984 def handle_ntf(self, decoded):
986 if self.include_raw:
988 op = self.rsp_by_value[decoded.cmd()]
989 attrs = self._decode(decoded.raw_attrs, op.attr_set.name)
991 attrs.update(self._decode_struct(decoded.raw, op.fixed_header))
995 self.async_msg_queue.put(msg)
997 def check_ntf(self):
1000 reply = self.sock.recv(self._recv_size, socket.MSG_DONTWAIT)
1005 self._recv_dbg_print(reply, nms)
1015 decoded = self.nlproto.decode(self, nl_msg, None)
1016 if decoded.cmd() not in self.async_msg_ids:
1020 self.handle_ntf(decoded)
1022 def poll_ntf(self, duration=None):
1025 selector.register(self.sock, selectors.EVENT_READ)
1029 yield self.async_msg_queue.get_nowait()
1039 self.check_ntf()
1041 def operation_do_attributes(self, name):
1046 op = self.find_operation(name)
1052 def _encode_message(self, op, vals, flags, req_seq):
1057 msg = self.nlproto.message(nl_flags, op.req_value, 1, req_seq)
1059 msg += self._encode_struct(op.fixed_header, vals)
1062 msg += self._add_attr(op.attr_set.name, name, value, search_attrs)
1066 def _ops(self, ops):
1071 op = self.ops[method]
1072 msg = self._encode_message(op, vals, flags, req_seq)
1077 self.sock.send(payload, 0)
1083 reply = self.sock.recv(self._recv_size)
1085 self._recv_dbg_print(reply, nms)
1091 self._decode_extack(req_msg, op, nl_msg.extack, vals)
1117 decoded = self.nlproto.decode(self, nl_msg, op)
1121 if decoded.cmd() in self.async_msg_ids:
1122 self.handle_ntf(decoded)
1128 rsp_msg = self._decode(decoded.raw_attrs, op.attr_set.name)
1130 rsp_msg.update(self._decode_struct(decoded.raw, op.fixed_header))
1135 def _op(self, method, vals, flags=None, dump=False):
1141 return self._ops(ops)[0]
1143 def do(self, method, vals, flags=None):
1144 return self._op(method, vals, flags)
1146 def dump(self, method, vals):
1147 return self._op(method, vals, dump=True)
1149 def do_multi(self, ops):
1150 return self._ops(ops)