@@ -594,7 +594,7 @@ def _add_attr(self, space, name, value, search_attrs):
594594 scalar_selector = self ._get_scalar (attr , value ["selector" ])
595595 attr_payload = struct .pack ("II" , scalar_value , scalar_selector )
596596 elif attr ['type' ] == 'sub-message' :
597- msg_format = self ._resolve_selector (attr , search_attrs )
597+ msg_format , _ = self ._resolve_selector (attr , search_attrs )
598598 attr_payload = b''
599599 if msg_format .fixed_header :
600600 attr_payload += self ._encode_struct (msg_format .fixed_header , value )
@@ -712,10 +712,10 @@ def _resolve_selector(self, attr_spec, search_attrs):
712712 raise Exception (f"No message format for '{ value } ' in sub-message spec '{ sub_msg } '" )
713713
714714 spec = sub_msg_spec .formats [value ]
715- return spec
715+ return spec , value
716716
717717 def _decode_sub_msg (self , attr , attr_spec , search_attrs ):
718- msg_format = self ._resolve_selector (attr_spec , search_attrs )
718+ msg_format , _ = self ._resolve_selector (attr_spec , search_attrs )
719719 decoded = {}
720720 offset = 0
721721 if msg_format .fixed_header :
@@ -787,7 +787,7 @@ def _decode(self, attrs, space, outer_attrs = None):
787787
788788 return rsp
789789
790- def _decode_extack_path (self , attrs , attr_set , offset , target ):
790+ def _decode_extack_path (self , attrs , attr_set , offset , target , search_attrs ):
791791 for attr in attrs :
792792 try :
793793 attr_spec = attr_set .attrs_by_val [attr .type ]
@@ -801,26 +801,37 @@ def _decode_extack_path(self, attrs, attr_set, offset, target):
801801 if offset + attr .full_len <= target :
802802 offset += attr .full_len
803803 continue
804- if attr_spec ['type' ] != 'nest' :
804+
805+ pathname = attr_spec .name
806+ if attr_spec ['type' ] == 'nest' :
807+ sub_attrs = self .attr_sets [attr_spec ['nested-attributes' ]]
808+ search_attrs = SpaceAttrs (sub_attrs , search_attrs .lookup (attr_spec ['name' ]))
809+ elif attr_spec ['type' ] == 'sub-message' :
810+ msg_format , value = self ._resolve_selector (attr_spec , search_attrs )
811+ if msg_format is None :
812+ raise Exception (f"Can't resolve sub-message of { attr_spec ['name' ]} for extack" )
813+ sub_attrs = self .attr_sets [msg_format .attr_set ]
814+ pathname += f"({ value } )"
815+ else :
805816 raise Exception (f"Can't dive into { attr .type } ({ attr_spec ['name' ]} ) for extack" )
806817 offset += 4
807- subpath = self ._decode_extack_path (NlAttrs (attr .raw ),
808- self .attr_sets [attr_spec ['nested-attributes' ]],
809- offset , target )
818+ subpath = self ._decode_extack_path (NlAttrs (attr .raw ), sub_attrs ,
819+ offset , target , search_attrs )
810820 if subpath is None :
811821 return None
812- return '.' + attr_spec . name + subpath
822+ return '.' + pathname + subpath
813823
814824 return None
815825
816- def _decode_extack (self , request , op , extack ):
826+ def _decode_extack (self , request , op , extack , vals ):
817827 if 'bad-attr-offs' not in extack :
818828 return
819829
820830 msg = self .nlproto .decode (self , NlMsg (request , 0 , op .attr_set ), op )
821831 offset = self .nlproto .msghdr_size () + self ._struct_size (op .fixed_header )
832+ search_attrs = SpaceAttrs (op .attr_set , vals )
822833 path = self ._decode_extack_path (msg .raw_attrs , op .attr_set , offset ,
823- extack ['bad-attr-offs' ])
834+ extack ['bad-attr-offs' ], search_attrs )
824835 if path :
825836 del extack ['bad-attr-offs' ]
826837 extack ['bad-attr' ] = path
@@ -1012,7 +1023,7 @@ def _ops(self, ops):
10121023 for (method , vals , flags ) in ops :
10131024 op = self .ops [method ]
10141025 msg = self ._encode_message (op , vals , flags , req_seq )
1015- reqs_by_seq [req_seq ] = (op , msg , flags )
1026+ reqs_by_seq [req_seq ] = (op , vals , msg , flags )
10161027 payload += msg
10171028 req_seq += 1
10181029
@@ -1027,9 +1038,9 @@ def _ops(self, ops):
10271038 self ._recv_dbg_print (reply , nms )
10281039 for nl_msg in nms :
10291040 if nl_msg .nl_seq in reqs_by_seq :
1030- (op , req_msg , req_flags ) = reqs_by_seq [nl_msg .nl_seq ]
1041+ (op , vals , req_msg , req_flags ) = reqs_by_seq [nl_msg .nl_seq ]
10311042 if nl_msg .extack :
1032- self ._decode_extack (req_msg , op , nl_msg .extack )
1043+ self ._decode_extack (req_msg , op , nl_msg .extack , vals )
10331044 else :
10341045 op = None
10351046 req_flags = []
0 commit comments