Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'tools-ynl-decode-link-types-present-in-tests'

Jakub Kicinski says:

====================
tools: ynl: decode link types present in tests

Using a kernel built for the net selftest target to run drivers/net
tests currently fails, because the net kernel automatically spawns
a handful of tunnel devices which YNL can't decode.

Fill in those missing link types in rt_link. We need to extend subset
support a bit for it to work.

v1: https://lore.kernel.org/20250105012523.1722231-1-kuba@kernel.org
====================

Link: https://patch.msgid.link/20250107022820.2087101-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+151 -39
+87
Documentation/netlink/specs/rt_link.yaml
··· 1826 1826 name: erspan-hwid 1827 1827 type: u16 1828 1828 - 1829 + name: linkinfo-vti-attrs 1830 + name-prefix: ifla-vti- 1831 + attributes: 1832 + - 1833 + name: link 1834 + type: u32 1835 + - 1836 + name: ikey 1837 + type: u32 1838 + - 1839 + name: okey 1840 + type: u32 1841 + - 1842 + name: local 1843 + type: binary 1844 + display-hint: ipv4 1845 + - 1846 + name: remote 1847 + type: binary 1848 + display-hint: ipv4 1849 + - 1850 + name: fwmark 1851 + type: u32 1852 + - 1853 + name: linkinfo-vti6-attrs 1854 + subset-of: linkinfo-vti-attrs 1855 + attributes: 1856 + - 1857 + name: link 1858 + - 1859 + name: ikey 1860 + - 1861 + name: okey 1862 + - 1863 + name: local 1864 + display-hint: ipv6 1865 + - 1866 + name: remote 1867 + display-hint: ipv6 1868 + - 1869 + name: fwmark 1870 + - 1829 1871 name: linkinfo-geneve-attrs 1830 1872 name-prefix: ifla-geneve- 1831 1873 attributes: ··· 1983 1941 - 1984 1942 name: fwmark 1985 1943 type: u32 1944 + - 1945 + name: linkinfo-ip6tnl-attrs 1946 + subset-of: linkinfo-iptun-attrs 1947 + attributes: 1948 + - 1949 + name: link 1950 + - 1951 + name: local 1952 + display-hint: ipv6 1953 + - 1954 + name: remote 1955 + display-hint: ipv6 1956 + - 1957 + name: ttl 1958 + - 1959 + name: encap-limit 1960 + - 1961 + name: flowinfo 1962 + - 1963 + name: flags 1964 + # ip6tnl unlike ipip and sit has 32b flags 1965 + type: u32 1966 + - 1967 + name: proto 1968 + - 1969 + name: encap-type 1970 + - 1971 + name: encap-flags 1972 + - 1973 + name: encap-sport 1974 + - 1975 + name: encap-dport 1976 + - 1977 + name: collect-metadata 1978 + - 1979 + name: fwmark 1986 1980 - 1987 1981 name: linkinfo-tun-attrs 1988 1982 name-prefix: ifla-tun- ··· 2280 2202 value: ipip 2281 2203 attribute-set: linkinfo-iptun-attrs 2282 2204 - 2205 + value: ip6tnl 2206 + attribute-set: linkinfo-ip6tnl-attrs 2207 + - 2283 2208 value: sit 2284 2209 attribute-set: linkinfo-iptun-attrs 2285 2210 - ··· 2294 2213 - 2295 2214 value: vrf 2296 2215 attribute-set: linkinfo-vrf-attrs 2216 + - 2217 + value: vti 2218 + attribute-set: linkinfo-vti-attrs 2219 + - 2220 + value: vti6 2221 + attribute-set: linkinfo-vti6-attrs 2297 2222 - 2298 2223 value: netkit 2299 2224 attribute-set: linkinfo-netkit-attrs
+4 -1
tools/net/ynl/lib/nlspec.py
··· 219 219 else: 220 220 real_set = family.attr_sets[self.subset_of] 221 221 for elem in self.yaml['attributes']: 222 - attr = real_set[elem['name']] 222 + real_attr = real_set[elem['name']] 223 + combined_elem = real_attr.yaml | elem 224 + attr = self.new_attr(combined_elem, real_attr.value) 225 + 223 226 self.attrs[attr.name] = attr 224 227 self.attrs_by_val[attr.value] = attr 225 228
+38 -34
tools/net/ynl/lib/ynl.py
··· 733 733 self._rsp_add(rsp, attr_name, None, self._decode_unknown(attr)) 734 734 continue 735 735 736 - if attr_spec["type"] == 'nest': 737 - subdict = self._decode(NlAttrs(attr.raw), attr_spec['nested-attributes'], search_attrs) 738 - decoded = subdict 739 - elif attr_spec["type"] == 'string': 740 - decoded = attr.as_strz() 741 - elif attr_spec["type"] == 'binary': 742 - decoded = self._decode_binary(attr, attr_spec) 743 - elif attr_spec["type"] == 'flag': 744 - decoded = True 745 - elif attr_spec.is_auto_scalar: 746 - decoded = attr.as_auto_scalar(attr_spec['type'], attr_spec.byte_order) 747 - elif attr_spec["type"] in NlAttr.type_formats: 748 - decoded = attr.as_scalar(attr_spec['type'], attr_spec.byte_order) 749 - if 'enum' in attr_spec: 750 - decoded = self._decode_enum(decoded, attr_spec) 751 - elif attr_spec.display_hint: 752 - decoded = self._formatted_string(decoded, attr_spec.display_hint) 753 - elif attr_spec["type"] == 'indexed-array': 754 - decoded = self._decode_array_attr(attr, attr_spec) 755 - elif attr_spec["type"] == 'bitfield32': 756 - value, selector = struct.unpack("II", attr.raw) 757 - if 'enum' in attr_spec: 758 - value = self._decode_enum(value, attr_spec) 759 - selector = self._decode_enum(selector, attr_spec) 760 - decoded = {"value": value, "selector": selector} 761 - elif attr_spec["type"] == 'sub-message': 762 - decoded = self._decode_sub_msg(attr, attr_spec, search_attrs) 763 - elif attr_spec["type"] == 'nest-type-value': 764 - decoded = self._decode_nest_type_value(attr, attr_spec) 765 - else: 766 - if not self.process_unknown: 767 - raise Exception(f'Unknown {attr_spec["type"]} with name {attr_spec["name"]}') 768 - decoded = self._decode_unknown(attr) 736 + try: 737 + if attr_spec["type"] == 'nest': 738 + subdict = self._decode(NlAttrs(attr.raw), attr_spec['nested-attributes'], search_attrs) 739 + decoded = subdict 740 + elif attr_spec["type"] == 'string': 741 + decoded = attr.as_strz() 742 + elif attr_spec["type"] == 'binary': 743 + decoded = self._decode_binary(attr, attr_spec) 744 + elif attr_spec["type"] == 'flag': 745 + decoded = True 746 + elif attr_spec.is_auto_scalar: 747 + decoded = attr.as_auto_scalar(attr_spec['type'], attr_spec.byte_order) 748 + elif attr_spec["type"] in NlAttr.type_formats: 749 + decoded = attr.as_scalar(attr_spec['type'], attr_spec.byte_order) 750 + if 'enum' in attr_spec: 751 + decoded = self._decode_enum(decoded, attr_spec) 752 + elif attr_spec.display_hint: 753 + decoded = self._formatted_string(decoded, attr_spec.display_hint) 754 + elif attr_spec["type"] == 'indexed-array': 755 + decoded = self._decode_array_attr(attr, attr_spec) 756 + elif attr_spec["type"] == 'bitfield32': 757 + value, selector = struct.unpack("II", attr.raw) 758 + if 'enum' in attr_spec: 759 + value = self._decode_enum(value, attr_spec) 760 + selector = self._decode_enum(selector, attr_spec) 761 + decoded = {"value": value, "selector": selector} 762 + elif attr_spec["type"] == 'sub-message': 763 + decoded = self._decode_sub_msg(attr, attr_spec, search_attrs) 764 + elif attr_spec["type"] == 'nest-type-value': 765 + decoded = self._decode_nest_type_value(attr, attr_spec) 766 + else: 767 + if not self.process_unknown: 768 + raise Exception(f'Unknown {attr_spec["type"]} with name {attr_spec["name"]}') 769 + decoded = self._decode_unknown(attr) 769 770 770 - self._rsp_add(rsp, attr_spec["name"], attr_spec.is_multi, decoded) 771 + self._rsp_add(rsp, attr_spec["name"], attr_spec.is_multi, decoded) 772 + except: 773 + print(f"Error decoding '{attr_spec.name}' from '{space}'") 774 + raise 771 775 772 776 return rsp 773 777
+22 -4
tools/net/ynl/ynl-gen-c.py
··· 79 79 self.enum_name = None 80 80 delattr(self, "enum_name") 81 81 82 + def _get_real_attr(self): 83 + # if the attr is for a subset return the "real" attr (just one down, does not recurse) 84 + return self.family.attr_sets[self.attr_set.subset_of][self.name] 85 + 86 + def set_request(self): 87 + self.request = True 88 + if self.attr_set.subset_of: 89 + self._get_real_attr().set_request() 90 + 91 + def set_reply(self): 92 + self.reply = True 93 + if self.attr_set.subset_of: 94 + self._get_real_attr().set_reply() 95 + 82 96 def get_limit(self, limit, default=None): 83 97 value = self.checks.get(limit, default) 84 98 if value is None: ··· 119 105 else: 120 106 enum_name = f"{self.attr_set.name_prefix}{self.name}" 121 107 self.enum_name = c_upper(enum_name) 108 + 109 + if self.attr_set.subset_of: 110 + if self.checks != self._get_real_attr().checks: 111 + raise Exception("Overriding checks not supported by codegen, yet") 122 112 123 113 def is_multi_val(self): 124 114 return None ··· 1137 1119 for _, struct in self.pure_nested_structs.items(): 1138 1120 if struct.request: 1139 1121 for _, arg in struct.member_list(): 1140 - arg.request = True 1122 + arg.set_request() 1141 1123 if struct.reply: 1142 1124 for _, arg in struct.member_list(): 1143 - arg.reply = True 1125 + arg.set_reply() 1144 1126 1145 1127 for root_set, rs_members in self.root_sets.items(): 1146 1128 for attr, spec in self.attr_sets[root_set].items(): 1147 1129 if attr in rs_members['request']: 1148 - spec.request = True 1130 + spec.set_request() 1149 1131 if attr in rs_members['reply']: 1150 - spec.reply = True 1132 + spec.set_reply() 1151 1133 1152 1134 def _load_global_policy(self): 1153 1135 global_set = set()