Skip to content

Commit fb0a06d

Browse files
donaldhkuba-moo
authored andcommitted
tools/net/ynl: Fix extack parsing with fixed header genlmsg
Move decode_fixed_header into YnlFamily and add a _fixed_header_size method to allow extack decoding to skip the fixed header. Signed-off-by: Donald Hunter <donald.hunter@gmail.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://lore.kernel.org/r/20230825122756.7603-7-donald.hunter@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 88901b9 commit fb0a06d

1 file changed

Lines changed: 40 additions & 25 deletions

File tree

tools/net/ynl/lib/ynl.py

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def _genl_load_families():
293293

294294
gm = GenlMsg(nl_msg)
295295
fam = dict()
296-
for attr in gm.raw_attrs:
296+
for attr in NlAttrs(gm.raw):
297297
if attr.type == Netlink.CTRL_ATTR_FAMILY_ID:
298298
fam['id'] = attr.as_scalar('u16')
299299
elif attr.type == Netlink.CTRL_ATTR_FAMILY_NAME:
@@ -317,23 +317,10 @@ def _genl_load_families():
317317

318318

319319
class GenlMsg:
320-
def __init__(self, nl_msg, fixed_header_members=[]):
320+
def __init__(self, nl_msg):
321321
self.nl = nl_msg
322-
323-
self.hdr = nl_msg.raw[0:4]
324-
offset = 4
325-
326-
self.genl_cmd, self.genl_version, _ = struct.unpack("BBH", self.hdr)
327-
328-
self.fixed_header_attrs = dict()
329-
for m in fixed_header_members:
330-
format = NlAttr.get_format(m.type, m.byte_order)
331-
decoded = format.unpack_from(nl_msg.raw, offset)
332-
offset += format.size
333-
self.fixed_header_attrs[m.name] = decoded[0]
334-
335-
self.raw = nl_msg.raw[offset:]
336-
self.raw_attrs = NlAttrs(self.raw)
322+
self.genl_cmd, self.genl_version, _ = struct.unpack_from("BBH", nl_msg.raw, 0)
323+
self.raw = nl_msg.raw[4:]
337324

338325
def __repr__(self):
339326
msg = repr(self.nl)
@@ -514,17 +501,44 @@ def _decode_extack_path(self, attrs, attr_set, offset, target):
514501

515502
return None
516503

517-
def _decode_extack(self, request, attr_space, extack):
504+
def _decode_extack(self, request, op, extack):
518505
if 'bad-attr-offs' not in extack:
519506
return
520507

521-
genl_req = GenlMsg(NlMsg(request, 0, attr_space=attr_space))
522-
path = self._decode_extack_path(genl_req.raw_attrs, attr_space,
523-
20, extack['bad-attr-offs'])
508+
genl_req = GenlMsg(NlMsg(request, 0, op.attr_set))
509+
fixed_header_size = self._fixed_header_size(op)
510+
offset = 20 + fixed_header_size
511+
path = self._decode_extack_path(NlAttrs(genl_req.raw[fixed_header_size:]),
512+
op.attr_set, offset,
513+
extack['bad-attr-offs'])
524514
if path:
525515
del extack['bad-attr-offs']
526516
extack['bad-attr'] = path
527517

518+
def _fixed_header_size(self, op):
519+
if op.fixed_header:
520+
fixed_header_members = self.consts[op.fixed_header].members
521+
size = 0
522+
for m in fixed_header_members:
523+
format = NlAttr.get_format(m.type, m.byte_order)
524+
size += format.size
525+
return size
526+
else:
527+
return 0
528+
529+
def _decode_fixed_header(self, msg, name):
530+
fixed_header_members = self.consts[name].members
531+
fixed_header_attrs = dict()
532+
offset = 0
533+
for m in fixed_header_members:
534+
format = NlAttr.get_format(m.type, m.byte_order)
535+
[ value ] = format.unpack_from(msg.raw, offset)
536+
offset += format.size
537+
if m.enum:
538+
value = self._decode_enum(value, m)
539+
fixed_header_attrs[m.name] = value
540+
return fixed_header_attrs
541+
528542
def handle_ntf(self, nl_msg, genl_msg):
529543
msg = dict()
530544
if self.include_raw:
@@ -599,7 +613,7 @@ def _op(self, method, vals, dump=False):
599613
nms = NlMsgs(reply, attr_space=op.attr_set)
600614
for nl_msg in nms:
601615
if nl_msg.extack:
602-
self._decode_extack(msg, op.attr_set, nl_msg.extack)
616+
self._decode_extack(msg, op, nl_msg.extack)
603617

604618
if nl_msg.error:
605619
raise NlError(nl_msg)
@@ -610,7 +624,7 @@ def _op(self, method, vals, dump=False):
610624
done = True
611625
break
612626

613-
gm = GenlMsg(nl_msg, fixed_header_members)
627+
gm = GenlMsg(nl_msg)
614628
# Check if this is a reply to our request
615629
if nl_msg.nl_seq != req_seq or gm.genl_cmd != op.rsp_value:
616630
if gm.genl_cmd in self.async_msg_ids:
@@ -620,8 +634,9 @@ def _op(self, method, vals, dump=False):
620634
print('Unexpected message: ' + repr(gm))
621635
continue
622636

623-
rsp_msg = self._decode(gm.raw_attrs, op.attr_set.name)
624-
rsp_msg.update(gm.fixed_header_attrs)
637+
rsp_msg = self._decode(NlAttrs(gm.raw), op.attr_set.name)
638+
if op.fixed_header:
639+
rsp_msg.update(self._decode_fixed_header(gm, op.fixed_header))
625640
rsp.append(rsp_msg)
626641

627642
if not rsp:

0 commit comments

Comments
 (0)