diff mbox series

[net-next,02/10] tools: ynl-gen: introduce support for bitfield32 attribute type

Message ID 20231010110828.200709-3-jiri@resnulli.us (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series devlink: finish conversion to generated split_ops | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/cc_maintainers warning 5 maintainers not CCed: chuck.lever@oracle.com willemb@google.com horms@kernel.org donald.hunter@gmail.com sdf@google.com
netdev/build_clang success Errors and warnings before: 9 this patch: 9
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 9 this patch: 9
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 135 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jiri Pirko Oct. 10, 2023, 11:08 a.m. UTC
From: Jiri Pirko <jiri@nvidia.com>

Introduce support for forgotten attribute type bitfield32.
Note that since the generated code works with struct nla_bitfiel32,
the generator adds netlink.h to the list of includes for userspace
headers. Regenerate the headers.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
 Documentation/netlink/genetlink-c.yaml      |  2 +-
 Documentation/netlink/genetlink-legacy.yaml |  4 +--
 Documentation/netlink/genetlink.yaml        |  2 +-
 tools/net/ynl/generated/devlink-user.h      |  1 +
 tools/net/ynl/generated/ethtool-user.h      |  1 +
 tools/net/ynl/generated/fou-user.h          |  1 +
 tools/net/ynl/generated/handshake-user.h    |  1 +
 tools/net/ynl/generated/netdev-user.h       |  1 +
 tools/net/ynl/lib/ynl.c                     |  6 ++++
 tools/net/ynl/lib/ynl.h                     |  1 +
 tools/net/ynl/ynl-gen-c.py                  | 31 +++++++++++++++++++++
 11 files changed, 47 insertions(+), 4 deletions(-)

Comments

Johannes Berg Oct. 10, 2023, 11:11 a.m. UTC | #1
On Tue, 2023-10-10 at 13:08 +0200, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@nvidia.com>
> 
> Introduce support for forgotten attribute type bitfield32.
> Note that since the generated code works with struct nla_bitfiel32,
                                                                  ^ typo

Otherwise, looks good.

Reviewed-by: Johannes Berg <johannes@sipsolutions.net>

johannes
Jakub Kicinski Oct. 10, 2023, 6:58 p.m. UTC | #2
On Tue, 10 Oct 2023 13:08:21 +0200 Jiri Pirko wrote:
> Introduce support for forgotten attribute type bitfield32.

s/forgotten//, no family need it so far

> Note that since the generated code works with struct nla_bitfiel32,
> the generator adds netlink.h to the list of includes for userspace
> headers. Regenerate the headers.

If all we need it for is bitfield32 it should be added dynamically.
bitfiled32 is an odd concept.

> diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml
> index f9366aaddd21..8192b87b3046 100644
> --- a/Documentation/netlink/genetlink-c.yaml
> +++ b/Documentation/netlink/genetlink-c.yaml
> @@ -144,7 +144,7 @@ properties:
>                name:
>                  type: string
>                type: &attr-type
> -                enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64,
> +                enum: [ unused, pad, flag, binary, bitfield32, u8, u16, u32, u64, s32, s64,
>                          string, nest, array-nest, nest-type-value ]

Just for genetlink-legacy, please.
Also I think you need to update Documentation.

> +class TypeBitfield32(Type):
> +    def arg_member(self, ri):
> +        return [f"const struct nla_bitfield32 *{self.c_name}"]
> +
> +    def struct_member(self, ri):
> +        ri.cw.p(f"struct nla_bitfield32 {self.c_name};")

I think that you can re-implement _complex_member_type() instead
of these two?
Jakub Kicinski Oct. 10, 2023, 7:01 p.m. UTC | #3
On Tue, 10 Oct 2023 13:08:21 +0200 Jiri Pirko wrote:
>  tools/net/ynl/lib/ynl.c                     |  6 ++++
>  tools/net/ynl/lib/ynl.h                     |  1 +
>  tools/net/ynl/ynl-gen-c.py                  | 31 +++++++++++++++++++++

"forgotten" to add support to tools/net/ynl/lib/ynl.py ? :]
Jiri Pirko Oct. 11, 2023, 6:06 a.m. UTC | #4
Tue, Oct 10, 2023 at 09:01:30PM CEST, kuba@kernel.org wrote:
>On Tue, 10 Oct 2023 13:08:21 +0200 Jiri Pirko wrote:
>>  tools/net/ynl/lib/ynl.c                     |  6 ++++
>>  tools/net/ynl/lib/ynl.h                     |  1 +
>>  tools/net/ynl/ynl-gen-c.py                  | 31 +++++++++++++++++++++
>
>"forgotten" to add support to tools/net/ynl/lib/ynl.py ? :]

Will check.
Jiri Pirko Oct. 11, 2023, 6:07 a.m. UTC | #5
Tue, Oct 10, 2023 at 08:58:04PM CEST, kuba@kernel.org wrote:
>On Tue, 10 Oct 2023 13:08:21 +0200 Jiri Pirko wrote:
>> Introduce support for forgotten attribute type bitfield32.
>
>s/forgotten//, no family need it so far
>
>> Note that since the generated code works with struct nla_bitfiel32,
>> the generator adds netlink.h to the list of includes for userspace
>> headers. Regenerate the headers.
>
>If all we need it for is bitfield32 it should be added dynamically.
>bitfiled32 is an odd concept.

What do you mean by "added dynamically"?


>
>> diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml
>> index f9366aaddd21..8192b87b3046 100644
>> --- a/Documentation/netlink/genetlink-c.yaml
>> +++ b/Documentation/netlink/genetlink-c.yaml
>> @@ -144,7 +144,7 @@ properties:
>>                name:
>>                  type: string
>>                type: &attr-type
>> -                enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64,
>> +                enum: [ unused, pad, flag, binary, bitfield32, u8, u16, u32, u64, s32, s64,
>>                          string, nest, array-nest, nest-type-value ]
>
>Just for genetlink-legacy, please.

Why? Should be usable for all, same as other types, no?


>Also I think you need to update Documentation.
>
>> +class TypeBitfield32(Type):
>> +    def arg_member(self, ri):
>> +        return [f"const struct nla_bitfield32 *{self.c_name}"]
>> +
>> +    def struct_member(self, ri):
>> +        ri.cw.p(f"struct nla_bitfield32 {self.c_name};")
>
>I think that you can re-implement _complex_member_type() instead
>of these two?

Will check.

>
Jakub Kicinski Oct. 11, 2023, 4:52 p.m. UTC | #6
On Wed, 11 Oct 2023 08:07:12 +0200 Jiri Pirko wrote:
> >> Note that since the generated code works with struct nla_bitfiel32,
> >> the generator adds netlink.h to the list of includes for userspace
> >> headers. Regenerate the headers.  
> >
> >If all we need it for is bitfield32 it should be added dynamically.
> >bitfiled32 is an odd concept.  
> 
> What do you mean by "added dynamically"?

Scan the family, see if it has any bitfields and only then add 
the include? It's not that common, no point slowing down compilation
for all families if the header is not otherwise needed.

> >> diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml
> >> index f9366aaddd21..8192b87b3046 100644
> >> --- a/Documentation/netlink/genetlink-c.yaml
> >> +++ b/Documentation/netlink/genetlink-c.yaml
> >> @@ -144,7 +144,7 @@ properties:
> >>                name:
> >>                  type: string
> >>                type: &attr-type
> >> -                enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64,
> >> +                enum: [ unused, pad, flag, binary, bitfield32, u8, u16, u32, u64, s32, s64,
> >>                          string, nest, array-nest, nest-type-value ]  
> >
> >Just for genetlink-legacy, please.  
> 
> Why? Should be usable for all, same as other types, no?

array-nest already isn't. I don't see much value in bitfiled32
and listing it means every future codegen for genetlink will
have to support it to be compatible. It's easier to add stuff
than to remove it, so let's not.
Jiri Pirko Oct. 11, 2023, 5:04 p.m. UTC | #7
Wed, Oct 11, 2023 at 06:52:36PM CEST, kuba@kernel.org wrote:
>On Wed, 11 Oct 2023 08:07:12 +0200 Jiri Pirko wrote:
>> >> Note that since the generated code works with struct nla_bitfiel32,
>> >> the generator adds netlink.h to the list of includes for userspace
>> >> headers. Regenerate the headers.  
>> >
>> >If all we need it for is bitfield32 it should be added dynamically.
>> >bitfiled32 is an odd concept.  
>> 
>> What do you mean by "added dynamically"?
>
>Scan the family, see if it has any bitfields and only then add 
>the include? It's not that common, no point slowing down compilation
>for all families if the header is not otherwise needed.

Got it. Will try.

>
>> >> diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml
>> >> index f9366aaddd21..8192b87b3046 100644
>> >> --- a/Documentation/netlink/genetlink-c.yaml
>> >> +++ b/Documentation/netlink/genetlink-c.yaml
>> >> @@ -144,7 +144,7 @@ properties:
>> >>                name:
>> >>                  type: string
>> >>                type: &attr-type
>> >> -                enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64,
>> >> +                enum: [ unused, pad, flag, binary, bitfield32, u8, u16, u32, u64, s32, s64,
>> >>                          string, nest, array-nest, nest-type-value ]  
>> >
>> >Just for genetlink-legacy, please.  
>> 
>> Why? Should be usable for all, same as other types, no?
>
>array-nest already isn't. I don't see much value in bitfiled32
>and listing it means every future codegen for genetlink will
>have to support it to be compatible. It's easier to add stuff
>than to remove it, so let's not.

Interesting. You want to somehow mark bitfield32 obsolete? But why is
it? I mean, what is the reason to discourage use of bitfield32?
Jakub Kicinski Oct. 11, 2023, 6:25 p.m. UTC | #8
On Wed, 11 Oct 2023 19:04:42 +0200 Jiri Pirko wrote:
> >> Why? Should be usable for all, same as other types, no?  
> >
> >array-nest already isn't. I don't see much value in bitfiled32
> >and listing it means every future codegen for genetlink will
> >have to support it to be compatible. It's easier to add stuff
> >than to remove it, so let's not.  
> 
> Interesting. You want to somehow mark bitfield32 obsolete? But why is
> it? I mean, what is the reason to discourage use of bitfield32?

It's a tradeoff between simplicity of base types and usefulness.
bitfield32 is not bad in any way, but:

 - it's 32b, new features/caps like to start with 64b
 - it doesn't support "by name" operations so ethtool didn't use it
 - it can be trivially re-implemented with 2 attrs

all in all there aren't very many new uses. So I think we should
put it in legacy for now. Maybe somehow mark it as being there due
to limited applicability rather than being "bad"?
Jiri Pirko Oct. 12, 2023, 9:28 a.m. UTC | #9
Wed, Oct 11, 2023 at 08:25:37PM CEST, kuba@kernel.org wrote:
>On Wed, 11 Oct 2023 19:04:42 +0200 Jiri Pirko wrote:
>> >> Why? Should be usable for all, same as other types, no?  
>> >
>> >array-nest already isn't. I don't see much value in bitfiled32
>> >and listing it means every future codegen for genetlink will
>> >have to support it to be compatible. It's easier to add stuff
>> >than to remove it, so let's not.  
>> 
>> Interesting. You want to somehow mark bitfield32 obsolete? But why is
>> it? I mean, what is the reason to discourage use of bitfield32?
>
>It's a tradeoff between simplicity of base types and usefulness.
>bitfield32 is not bad in any way, but:
>
> - it's 32b, new features/caps like to start with 64b

That's fun. Back when Jamal (I think it was him) was pushing bitfield32,
I argued that it would be better to make it flexible bitfield so it it
future proof. IIRC DavidM said that it should be enough and that you can
use extra attr in case the current one overflows.

Sigh :/

> - it doesn't support "by name" operations so ethtool didn't use it

It follows the original Netlink rule: "all uapi should be well defined in
enums/defines".


> - it can be trivially re-implemented with 2 attrs

Yeah, it's basically a wrapper to avoid unnecessary boilerplate and
re-implementations. But I think that is a good thing. Or do you say it
is not desirable to rather re-implement this with 2 attrs instead of
using bitfield32 directly? 


>
>all in all there aren't very many new uses. So I think we should
>put it in legacy for now. Maybe somehow mark it as being there due
>to limited applicability rather than being "bad"?

I think it is odd, but if you insists, sure. Your the boss.
Jacob Keller Oct. 12, 2023, 9:06 p.m. UTC | #10
On 10/12/2023 2:28 AM, Jiri Pirko wrote:
> Wed, Oct 11, 2023 at 08:25:37PM CEST, kuba@kernel.org wrote:
>> On Wed, 11 Oct 2023 19:04:42 +0200 Jiri Pirko wrote:
>>>>> Why? Should be usable for all, same as other types, no?  
>>>>
>>>> array-nest already isn't. I don't see much value in bitfiled32
>>>> and listing it means every future codegen for genetlink will
>>>> have to support it to be compatible. It's easier to add stuff
>>>> than to remove it, so let's not.  
>>>
>>> Interesting. You want to somehow mark bitfield32 obsolete? But why is
>>> it? I mean, what is the reason to discourage use of bitfield32?
>>
>> It's a tradeoff between simplicity of base types and usefulness.
>> bitfield32 is not bad in any way, but:
>>
>> - it's 32b, new features/caps like to start with 64b
> 

To me, this is the biggest annoyance with bitfield32: that its not
flexible in size, which is one of the big benefits of netlink. That
limits bitfield32 to be most useful in places where you don't expect any
such extension.

> That's fun. Back when Jamal (I think it was him) was pushing bitfield32,
> I argued that it would be better to make it flexible bitfield so it it
> future proof. IIRC DavidM said that it should be enough and that you can
> use extra attr in case the current one overflows.
> 
> Sigh :/
> 
I don't like that approach because it means you need different handling
for different sets of bits which can be a bit frustrating. I would have
also preferred flexible bitfield as well.

>> - it doesn't support "by name" operations so ethtool didn't use it
> 
> It follows the original Netlink rule: "all uapi should be well defined in
> enums/defines".
> 

What's the "by name" operation?

> 
>> - it can be trivially re-implemented with 2 attrs
> 
> Yeah, it's basically a wrapper to avoid unnecessary boilerplate and
> re-implementations. But I think that is a good thing. Or do you say it
> is not desirable to rather re-implement this with 2 attrs instead of
> using bitfield32 directly? 
> 

This reads to me as "its easy to re-implement with 2 attributes rather
than baking them into one", and those attributes can support varying
sizes instead of just bitfield32
Jakub Kicinski Oct. 13, 2023, 12:15 a.m. UTC | #11
On Thu, 12 Oct 2023 14:06:57 -0700 Jacob Keller wrote:
> >> - it doesn't support "by name" operations so ethtool didn't use it  
> > 
> > It follows the original Netlink rule: "all uapi should be well defined in
> > enums/defines".
> 
> What's the "by name" operation?

Instead of sending the full bit mask sending the list of bits and what
state we want them in. And that list can either have bit numbers or
names. Looking at ethnl_parse_bit() could be helpful.
Jakub Kicinski Oct. 13, 2023, 12:25 a.m. UTC | #12
On Thu, 12 Oct 2023 11:28:40 +0200 Jiri Pirko wrote:
>> all in all there aren't very many new uses. So I think we should
>> put it in legacy for now. Maybe somehow mark it as being there due
>> to limited applicability rather than being "bad"?  
> 
> I think it is odd, but if you insists, sure. Your the boss.

Just to be clear here - we're talking about what goes into which
level of compatibility within YNL. So yes, I wrote YNL, I'd prefer 
to retain the ability to make some decisions about it :(
Jacob Keller Oct. 13, 2023, 6:49 p.m. UTC | #13
On 10/12/2023 5:15 PM, Jakub Kicinski wrote:
> On Thu, 12 Oct 2023 14:06:57 -0700 Jacob Keller wrote:
>>>> - it doesn't support "by name" operations so ethtool didn't use it  
>>>
>>> It follows the original Netlink rule: "all uapi should be well defined in
>>> enums/defines".
>>
>> What's the "by name" operation?
> 
> Instead of sending the full bit mask sending the list of bits and what
> state we want them in. And that list can either have bit numbers or
> names. Looking at ethnl_parse_bit() could be helpful.
> 

Ah, yep. Thanks for the clarification.

-Jake
diff mbox series

Patch

diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml
index f9366aaddd21..8192b87b3046 100644
--- a/Documentation/netlink/genetlink-c.yaml
+++ b/Documentation/netlink/genetlink-c.yaml
@@ -144,7 +144,7 @@  properties:
               name:
                 type: string
               type: &attr-type
-                enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64,
+                enum: [ unused, pad, flag, binary, bitfield32, u8, u16, u32, u64, s32, s64,
                         string, nest, array-nest, nest-type-value ]
               doc:
                 description: Documentation of the attribute.
diff --git a/Documentation/netlink/genetlink-legacy.yaml b/Documentation/netlink/genetlink-legacy.yaml
index a6a490333a1a..8b867b5b9966 100644
--- a/Documentation/netlink/genetlink-legacy.yaml
+++ b/Documentation/netlink/genetlink-legacy.yaml
@@ -120,7 +120,7 @@  properties:
                 type: string
               type:
                 description: The netlink attribute type
-                enum: [ u8, u16, u32, u64, s8, s16, s32, s64, string, binary ]
+                enum: [ u8, u16, u32, u64, s8, s16, s32, s64, string, binary, bitfield32 ]
               len:
                 $ref: '#/$defs/len-or-define'
               byte-order:
@@ -187,7 +187,7 @@  properties:
                 type: string
               type: &attr-type
                 description: The netlink attribute type
-                enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64,
+                enum: [ unused, pad, flag, binary, bitfield32, u8, u16, u32, u64, s32, s64,
                         string, nest, array-nest, nest-type-value ]
               doc:
                 description: Documentation of the attribute.
diff --git a/Documentation/netlink/genetlink.yaml b/Documentation/netlink/genetlink.yaml
index 2b788e607a14..5cde1b030e8e 100644
--- a/Documentation/netlink/genetlink.yaml
+++ b/Documentation/netlink/genetlink.yaml
@@ -117,7 +117,7 @@  properties:
               name:
                 type: string
               type: &attr-type
-                enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64,
+                enum: [ unused, pad, flag, binary, bitfield32, u8, u16, u32, u64, s32, s64,
                         string, nest, array-nest, nest-type-value ]
               doc:
                 description: Documentation of the attribute.
diff --git a/tools/net/ynl/generated/devlink-user.h b/tools/net/ynl/generated/devlink-user.h
index 4b686d147613..a490466fb98a 100644
--- a/tools/net/ynl/generated/devlink-user.h
+++ b/tools/net/ynl/generated/devlink-user.h
@@ -9,6 +9,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 #include <linux/types.h>
+#include <linux/netlink.h>
 #include <linux/devlink.h>
 
 struct ynl_sock;
diff --git a/tools/net/ynl/generated/ethtool-user.h b/tools/net/ynl/generated/ethtool-user.h
index ddc1a5209992..f7bce36f8485 100644
--- a/tools/net/ynl/generated/ethtool-user.h
+++ b/tools/net/ynl/generated/ethtool-user.h
@@ -10,6 +10,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 #include <linux/types.h>
+#include <linux/netlink.h>
 #include <linux/ethtool.h>
 
 struct ynl_sock;
diff --git a/tools/net/ynl/generated/fou-user.h b/tools/net/ynl/generated/fou-user.h
index a8f860892540..2ae6d1b66393 100644
--- a/tools/net/ynl/generated/fou-user.h
+++ b/tools/net/ynl/generated/fou-user.h
@@ -9,6 +9,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 #include <linux/types.h>
+#include <linux/netlink.h>
 #include <linux/fou.h>
 
 struct ynl_sock;
diff --git a/tools/net/ynl/generated/handshake-user.h b/tools/net/ynl/generated/handshake-user.h
index 2b34acc608de..1007f8db5c5e 100644
--- a/tools/net/ynl/generated/handshake-user.h
+++ b/tools/net/ynl/generated/handshake-user.h
@@ -9,6 +9,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 #include <linux/types.h>
+#include <linux/netlink.h>
 #include <linux/handshake.h>
 
 struct ynl_sock;
diff --git a/tools/net/ynl/generated/netdev-user.h b/tools/net/ynl/generated/netdev-user.h
index b4351ff34595..d6ffc0c8ccf4 100644
--- a/tools/net/ynl/generated/netdev-user.h
+++ b/tools/net/ynl/generated/netdev-user.h
@@ -9,6 +9,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 #include <linux/types.h>
+#include <linux/netlink.h>
 #include <linux/netdev.h>
 
 struct ynl_sock;
diff --git a/tools/net/ynl/lib/ynl.c b/tools/net/ynl/lib/ynl.c
index 514e0d69e731..4a94ef092b6e 100644
--- a/tools/net/ynl/lib/ynl.c
+++ b/tools/net/ynl/lib/ynl.c
@@ -373,6 +373,12 @@  int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr)
 		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
 		     "Invalid attribute (string %s)", policy->name);
 		return -1;
+	case YNL_PT_BITFIELD32:
+		if (len == sizeof(struct nla_bitfield32))
+			break;
+		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
+		     "Invalid attribute (bitfield32 %s)", policy->name);
+		return -1;
 	default:
 		yerr(yarg->ys, YNL_ERROR_ATTR_INVALID,
 		     "Invalid attribute (unknown %s)", policy->name);
diff --git a/tools/net/ynl/lib/ynl.h b/tools/net/ynl/lib/ynl.h
index 9eafa3552c16..813b26a08145 100644
--- a/tools/net/ynl/lib/ynl.h
+++ b/tools/net/ynl/lib/ynl.h
@@ -134,6 +134,7 @@  enum ynl_policy_type {
 	YNL_PT_U32,
 	YNL_PT_U64,
 	YNL_PT_NUL_STR,
+	YNL_PT_BITFIELD32,
 };
 
 struct ynl_policy_attr {
diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py
index f125b5f704ba..27bbe376054d 100755
--- a/tools/net/ynl/ynl-gen-c.py
+++ b/tools/net/ynl/ynl-gen-c.py
@@ -433,6 +433,34 @@  class TypeBinary(Type):
                 f'memcpy({member}, {self.c_name}, {presence}_len);']
 
 
+class TypeBitfield32(Type):
+    def arg_member(self, ri):
+        return [f"const struct nla_bitfield32 *{self.c_name}"]
+
+    def struct_member(self, ri):
+        ri.cw.p(f"struct nla_bitfield32 {self.c_name};")
+
+    def _attr_typol(self):
+        return f'.type = YNL_PT_BITFIELD32, '
+
+    def _attr_policy(self, policy):
+        if not 'enum' in self.attr:
+            raise Exception('Enum required for bitfield32 attr')
+        enum = self.family.consts[self.attr['enum']]
+        mask = enum.get_mask(as_flags=True)
+        return f"NLA_POLICY_BITFIELD32({mask})"
+
+    def attr_put(self, ri, var):
+        line = f"mnl_attr_put(nlh, {self.enum_name}, sizeof(struct nla_bitfield32), &{var}->{self.c_name})"
+        self._attr_put_line(ri, var, line)
+
+    def _attr_get(self, ri, var):
+        return f"memcpy(&{var}->{self.c_name}, mnl_attr_get_payload(attr), sizeof(struct nla_bitfield32));", None, None
+
+    def _setter_lines(self, ri, member, presence):
+        return [f"memcpy(&{member}, {self.c_name}, sizeof(struct nla_bitfield32));"]
+
+
 class TypeNest(Type):
     def _complex_member_type(self, ri):
         return self.nested_struct_type
@@ -735,6 +763,8 @@  class AttrSet(SpecAttrSet):
             t = TypeString(self.family, self, elem, value)
         elif elem['type'] == 'binary':
             t = TypeBinary(self.family, self, elem, value)
+        elif elem['type'] == 'bitfield32':
+            t = TypeBitfield32(self.family, self, elem, value)
         elif elem['type'] == 'nest':
             t = TypeNest(self.family, self, elem, value)
         elif elem['type'] == 'array-nest':
@@ -2406,6 +2436,7 @@  def main():
         cw.p('#include <string.h>')
         if args.header:
             cw.p('#include <linux/types.h>')
+            cw.p('#include <linux/netlink.h>')
         else:
             cw.p(f'#include "{parsed.name}-user.h"')
             cw.p('#include "ynl.h"')