@@ -594,7 +594,7 @@ def _add_attr(self, space, name, value, search_attrs):
594
594
scalar_selector = self ._get_scalar (attr , value ["selector" ])
595
595
attr_payload = struct .pack ("II" , scalar_value , scalar_selector )
596
596
elif attr ['type' ] == 'sub-message' :
597
- msg_format = self ._resolve_selector (attr , search_attrs )
597
+ msg_format , _ = self ._resolve_selector (attr , search_attrs )
598
598
attr_payload = b''
599
599
if msg_format .fixed_header :
600
600
attr_payload += self ._encode_struct (msg_format .fixed_header , value )
@@ -712,10 +712,10 @@ def _resolve_selector(self, attr_spec, search_attrs):
712
712
raise Exception (f"No message format for '{ value } ' in sub-message spec '{ sub_msg } '" )
713
713
714
714
spec = sub_msg_spec .formats [value ]
715
- return spec
715
+ return spec , value
716
716
717
717
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 )
719
719
decoded = {}
720
720
offset = 0
721
721
if msg_format .fixed_header :
@@ -787,7 +787,7 @@ def _decode(self, attrs, space, outer_attrs = None):
787
787
788
788
return rsp
789
789
790
- def _decode_extack_path (self , attrs , attr_set , offset , target ):
790
+ def _decode_extack_path (self , attrs , attr_set , offset , target , search_attrs ):
791
791
for attr in attrs :
792
792
try :
793
793
attr_spec = attr_set .attrs_by_val [attr .type ]
@@ -801,26 +801,37 @@ def _decode_extack_path(self, attrs, attr_set, offset, target):
801
801
if offset + attr .full_len <= target :
802
802
offset += attr .full_len
803
803
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 :
805
816
raise Exception (f"Can't dive into { attr .type } ({ attr_spec ['name' ]} ) for extack" )
806
817
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 )
810
820
if subpath is None :
811
821
return None
812
- return '.' + attr_spec . name + subpath
822
+ return '.' + pathname + subpath
813
823
814
824
return None
815
825
816
- def _decode_extack (self , request , op , extack ):
826
+ def _decode_extack (self , request , op , extack , vals ):
817
827
if 'bad-attr-offs' not in extack :
818
828
return
819
829
820
830
msg = self .nlproto .decode (self , NlMsg (request , 0 , op .attr_set ), op )
821
831
offset = self .nlproto .msghdr_size () + self ._struct_size (op .fixed_header )
832
+ search_attrs = SpaceAttrs (op .attr_set , vals )
822
833
path = self ._decode_extack_path (msg .raw_attrs , op .attr_set , offset ,
823
- extack ['bad-attr-offs' ])
834
+ extack ['bad-attr-offs' ], search_attrs )
824
835
if path :
825
836
del extack ['bad-attr-offs' ]
826
837
extack ['bad-attr' ] = path
@@ -1012,7 +1023,7 @@ def _ops(self, ops):
1012
1023
for (method , vals , flags ) in ops :
1013
1024
op = self .ops [method ]
1014
1025
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 )
1016
1027
payload += msg
1017
1028
req_seq += 1
1018
1029
@@ -1027,9 +1038,9 @@ def _ops(self, ops):
1027
1038
self ._recv_dbg_print (reply , nms )
1028
1039
for nl_msg in nms :
1029
1040
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 ]
1031
1042
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 )
1033
1044
else :
1034
1045
op = None
1035
1046
req_flags = []
0 commit comments