nl-linux 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +3 -0
  3. data/CHANGELOG.md +2 -0
  4. data/Rakefile +13 -3
  5. data/generated/nl/linux/binder.rb +80 -0
  6. data/generated/nl/linux/conntrack.rb +39 -2
  7. data/generated/nl/linux/dev_energymodel.rb +106 -0
  8. data/generated/nl/linux/devlink.rb +751 -0
  9. data/generated/nl/linux/dpll.rb +712 -55
  10. data/generated/nl/linux/drm_ras.rb +87 -0
  11. data/generated/nl/linux/ethtool.rb +1569 -259
  12. data/generated/nl/linux/fou.rb +82 -13
  13. data/generated/nl/linux/handshake.rb +92 -0
  14. data/generated/nl/linux/lockd.rb +50 -0
  15. data/generated/nl/linux/mptcp_pm.rb +159 -0
  16. data/generated/nl/linux/net_shaper.rb +123 -0
  17. data/generated/nl/linux/netdev.rb +374 -0
  18. data/generated/nl/linux/nfsd.rb +316 -6
  19. data/generated/nl/linux/nftables.rb +414 -25
  20. data/generated/nl/linux/nl80211.rb +81 -22
  21. data/generated/nl/linux/nlctrl.rb +59 -8
  22. data/generated/nl/linux/ovpn.rb +180 -0
  23. data/generated/nl/linux/ovs_datapath.rb +55 -6
  24. data/generated/nl/linux/ovs_flow.rb +63 -20
  25. data/generated/nl/linux/ovs_packet.rb +115 -4
  26. data/generated/nl/linux/ovs_vport.rb +55 -6
  27. data/generated/nl/linux/psp.rb +257 -0
  28. data/generated/nl/linux/rt_addr.rb +69 -14
  29. data/generated/nl/linux/rt_link.rb +381 -47
  30. data/generated/nl/linux/rt_neigh.rb +227 -16
  31. data/generated/nl/linux/rt_route.rb +92 -49
  32. data/generated/nl/linux/rt_rule.rb +300 -11
  33. data/generated/nl/linux/sunrpc_cache.rb +130 -0
  34. data/generated/nl/linux/tc.rb +161 -52
  35. data/generated/nl/linux/tcp_metrics.rb +69 -12
  36. data/generated/nl/linux/team.rb +80 -0
  37. data/generated/nl/linux/wireguard.rb +99 -7
  38. data/lib/nl/linux/version.rb +1 -1
  39. metadata +11 -9
@@ -1,4 +1,6 @@
1
1
  # SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
2
+ #
3
+ # This file is based on Documentation/netlink/specs/team.yaml from Linux v7.2.
2
4
  #--
3
5
  # frozen_string_literal: true
4
6
  # rbs_inline: enabled
@@ -9,6 +11,7 @@ module Nl; module Linux
9
11
  class Team < ::Nl::Family
10
12
  NAME = "team"
11
13
  PROTOCOL = Ractor.make_shareable(::Nl::Protocols::Genl.new("team"))
14
+ MCAST_GROUPS = Ractor.make_shareable({}) #: Hash[::Symbol, ::Nl::McastGroup]
12
15
  module Structs
13
16
  end
14
17
  module AttributeSets
@@ -223,6 +226,13 @@ class Team < ::Nl::Family
223
226
  ItemPort::Port::DATATYPE = ::Nl::Protocols::Genl::DataTypes::NestedAttributes.new(AttrPort)
224
227
  end
225
228
  module Messages
229
+ # No operation
230
+ class DoNoopRequest < ::Nl::Protocols::Genl::Message
231
+ TYPE = 0
232
+ FIXED_HEADER = nil
233
+ ATTRIBUTE_SET = AttributeSets::Team
234
+ ATTRIBUTES = Ractor.make_shareable(%i[])
235
+ end
226
236
  # No operation
227
237
  class DoNoopReply < ::Nl::Protocols::Genl::Message
228
238
  TYPE = 0
@@ -235,6 +245,8 @@ class Team < ::Nl::Family
235
245
  def team_ifindex; attributes[:"team_ifindex"]&.value; end
236
246
  end
237
247
  # Set team options
248
+ #
249
+ # Requires CAP_NET_ADMIN in the initial user namespace.
238
250
  class DoOptionsSetRequest < ::Nl::Protocols::Genl::Message
239
251
  TYPE = 1
240
252
  FIXED_HEADER = nil
@@ -250,6 +262,8 @@ class Team < ::Nl::Family
250
262
  def list_option; attributes[:"list_option"]&.value; end
251
263
  end
252
264
  # Set team options
265
+ #
266
+ # Requires CAP_NET_ADMIN in the initial user namespace.
253
267
  class DoOptionsSetReply < ::Nl::Protocols::Genl::Message
254
268
  TYPE = 1
255
269
  FIXED_HEADER = nil
@@ -265,6 +279,8 @@ class Team < ::Nl::Family
265
279
  def list_option; attributes[:"list_option"]&.value; end
266
280
  end
267
281
  # Get team options info
282
+ #
283
+ # Requires CAP_NET_ADMIN in the initial user namespace.
268
284
  class DoOptionsGetRequest < ::Nl::Protocols::Genl::Message
269
285
  TYPE = 2
270
286
  FIXED_HEADER = nil
@@ -276,6 +292,8 @@ class Team < ::Nl::Family
276
292
  def team_ifindex; attributes[:"team_ifindex"]&.value; end
277
293
  end
278
294
  # Get team options info
295
+ #
296
+ # Requires CAP_NET_ADMIN in the initial user namespace.
279
297
  class DoOptionsGetReply < ::Nl::Protocols::Genl::Message
280
298
  TYPE = 2
281
299
  FIXED_HEADER = nil
@@ -291,6 +309,8 @@ class Team < ::Nl::Family
291
309
  def list_option; attributes[:"list_option"]&.value; end
292
310
  end
293
311
  # Get team ports info
312
+ #
313
+ # Requires CAP_NET_ADMIN in the initial user namespace.
294
314
  class DoPortListGetRequest < ::Nl::Protocols::Genl::Message
295
315
  TYPE = 3
296
316
  FIXED_HEADER = nil
@@ -302,6 +322,8 @@ class Team < ::Nl::Family
302
322
  def team_ifindex; attributes[:"team_ifindex"]&.value; end
303
323
  end
304
324
  # Get team ports info
325
+ #
326
+ # Requires CAP_NET_ADMIN in the initial user namespace.
305
327
  class DoPortListGetReply < ::Nl::Protocols::Genl::Message
306
328
  TYPE = 3
307
329
  FIXED_HEADER = nil
@@ -317,23 +339,81 @@ class Team < ::Nl::Family
317
339
  def list_port; attributes[:"list_port"]&.value; end
318
340
  end
319
341
  end
342
+ module Notifications
343
+ end
344
+ NOTIFICATIONS = Ractor.make_shareable({}) #: Hash[::Integer, ::Class]
345
+ # No operation
346
+ #--
347
+ # @rbs () -> Messages::DoNoopReply
348
+ def do_noop(**args)
349
+ exchange_message(:"do", Messages::DoNoopRequest, Messages::DoNoopReply, args)
350
+ end
320
351
  # Set team options
352
+ #
353
+ # Requires CAP_NET_ADMIN in the initial user namespace.
321
354
  #--
322
355
  # @rbs (?team_ifindex: ::Integer, ?list_option: AttributeSets::ItemOption) -> Messages::DoOptionsSetReply
323
356
  def do_options_set(**args)
324
357
  exchange_message(:"do", Messages::DoOptionsSetRequest, Messages::DoOptionsSetReply, args)
325
358
  end
326
359
  # Get team options info
360
+ #
361
+ # Requires CAP_NET_ADMIN in the initial user namespace.
327
362
  #--
328
363
  # @rbs (?team_ifindex: ::Integer) -> Messages::DoOptionsGetReply
329
364
  def do_options_get(**args)
330
365
  exchange_message(:"do", Messages::DoOptionsGetRequest, Messages::DoOptionsGetReply, args)
331
366
  end
332
367
  # Get team ports info
368
+ #
369
+ # Requires CAP_NET_ADMIN in the initial user namespace.
333
370
  #--
334
371
  # @rbs (?team_ifindex: ::Integer) -> Messages::DoPortListGetReply
335
372
  def do_port_list_get(**args)
336
373
  exchange_message(:"do", Messages::DoPortListGetRequest, Messages::DoPortListGetReply, args)
337
374
  end
375
+ class AsyncOperations
376
+ # :nodoc:
377
+ def initialize(&exchange)
378
+ @exchange = exchange
379
+ end
380
+ # No operation
381
+ #--
382
+ # @rbs () -> ::Nl::Async::Future[Messages::DoNoopReply]
383
+ def do_noop(**args)
384
+ @exchange.call(:"do", Messages::DoNoopRequest, Messages::DoNoopReply, args)
385
+ end
386
+ # Set team options
387
+ #
388
+ # Requires CAP_NET_ADMIN in the initial user namespace.
389
+ #--
390
+ # @rbs (?team_ifindex: ::Integer, ?list_option: AttributeSets::ItemOption) -> ::Nl::Async::Future[Messages::DoOptionsSetReply]
391
+ def do_options_set(**args)
392
+ @exchange.call(:"do", Messages::DoOptionsSetRequest, Messages::DoOptionsSetReply, args)
393
+ end
394
+ # Get team options info
395
+ #
396
+ # Requires CAP_NET_ADMIN in the initial user namespace.
397
+ #--
398
+ # @rbs (?team_ifindex: ::Integer) -> ::Nl::Async::Future[Messages::DoOptionsGetReply]
399
+ def do_options_get(**args)
400
+ @exchange.call(:"do", Messages::DoOptionsGetRequest, Messages::DoOptionsGetReply, args)
401
+ end
402
+ # Get team ports info
403
+ #
404
+ # Requires CAP_NET_ADMIN in the initial user namespace.
405
+ #--
406
+ # @rbs (?team_ifindex: ::Integer) -> ::Nl::Async::Future[Messages::DoPortListGetReply]
407
+ def do_port_list_get(**args)
408
+ @exchange.call(:"do", Messages::DoPortListGetRequest, Messages::DoPortListGetReply, args)
409
+ end
410
+ end
411
+ # Returns the asynchronous operation facade for this family.
412
+ #--
413
+ # @rbs (?stream_capacity: ::Integer?) -> AsyncOperations
414
+ def async(stream_capacity: nil)
415
+ return @async_operations ||= build_async_facade(AsyncOperations) if stream_capacity.nil?
416
+ build_async_facade(AsyncOperations, stream_capacity:)
417
+ end
338
418
  end
339
419
  end; end
@@ -1,4 +1,6 @@
1
1
  # SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
2
+ #
3
+ # This file is based on Documentation/netlink/specs/wireguard.yaml from Linux v7.2.
2
4
  #--
3
5
  # frozen_string_literal: true
4
6
  # rbs_inline: enabled
@@ -16,6 +18,7 @@ module Nl; module Linux
16
18
  class Wireguard < ::Nl::Family
17
19
  NAME = "wireguard"
18
20
  PROTOCOL = Ractor.make_shareable(::Nl::Protocols::Genl.new("wireguard"))
21
+ MCAST_GROUPS = Ractor.make_shareable({}) #: Hash[::Symbol, ::Nl::McastGroup]
19
22
  module Structs
20
23
  KernelTimespec = Struct.new(
21
24
  :"sec", #: ::Integer
@@ -240,6 +243,9 @@ class Wireguard < ::Nl::Family
240
243
  # be ``NLMSG_DONE``, even if an error occurs. However, this ``NLMSG_DONE``
241
244
  # message contains an integer error code. It is either zero or a negative
242
245
  # error code corresponding to the errno.
246
+ #
247
+ #
248
+ # Requires CAP_NET_ADMIN in the user namespace owning the network namespace.
243
249
  class DumpGetDeviceRequest < ::Nl::Protocols::Genl::Message
244
250
  TYPE = 0
245
251
  FIXED_HEADER = nil
@@ -278,6 +284,9 @@ class Wireguard < ::Nl::Family
278
284
  # be ``NLMSG_DONE``, even if an error occurs. However, this ``NLMSG_DONE``
279
285
  # message contains an integer error code. It is either zero or a negative
280
286
  # error code corresponding to the errno.
287
+ #
288
+ #
289
+ # Requires CAP_NET_ADMIN in the user namespace owning the network namespace.
281
290
  class DumpGetDeviceReply < ::Nl::Protocols::Genl::Message
282
291
  TYPE = 0
283
292
  FIXED_HEADER = nil
@@ -293,11 +302,11 @@ class Wireguard < ::Nl::Family
293
302
  def ifname; attributes[:"ifname"]&.value; end
294
303
  # Gets the value of `private-key` attribute in the message.
295
304
  #--
296
- # @rbs return: untyped
305
+ # @rbs return: ::String
297
306
  def private_key; attributes[:"private_key"]&.value; end
298
307
  # Gets the value of `public-key` attribute in the message.
299
308
  #--
300
- # @rbs return: untyped
309
+ # @rbs return: ::String
301
310
  def public_key; attributes[:"public_key"]&.value; end
302
311
  # Gets the value of `flags` attribute in the message.
303
312
  #--
@@ -313,7 +322,7 @@ class Wireguard < ::Nl::Family
313
322
  def fwmark; attributes[:"fwmark"]&.value; end
314
323
  # Gets the value of `peers` attribute in the message.
315
324
  #--
316
- # @rbs return: untyped
325
+ # @rbs return: ::Array[AttributeSets::Wgpeer]
317
326
  def peers; attributes[:"peers"]&.value; end
318
327
  end
319
328
  # Set WireGuard device
@@ -334,6 +343,9 @@ class Wireguard < ::Nl::Family
334
343
  # subsequent fragments.
335
344
  #
336
345
  # If an error occurs, ``NLMSG_ERROR`` will reply containing an errno.
346
+ #
347
+ #
348
+ # Requires CAP_NET_ADMIN in the user namespace owning the network namespace.
337
349
  class DoSetDeviceRequest < ::Nl::Protocols::Genl::Message
338
350
  TYPE = 1
339
351
  FIXED_HEADER = nil
@@ -349,11 +361,11 @@ class Wireguard < ::Nl::Family
349
361
  def ifname; attributes[:"ifname"]&.value; end
350
362
  # Gets the value of `private-key` attribute in the message.
351
363
  #--
352
- # @rbs return: untyped
364
+ # @rbs return: ::String
353
365
  def private_key; attributes[:"private_key"]&.value; end
354
366
  # Gets the value of `public-key` attribute in the message.
355
367
  #--
356
- # @rbs return: untyped
368
+ # @rbs return: ::String
357
369
  def public_key; attributes[:"public_key"]&.value; end
358
370
  # Gets the value of `flags` attribute in the message.
359
371
  #--
@@ -369,10 +381,13 @@ class Wireguard < ::Nl::Family
369
381
  def fwmark; attributes[:"fwmark"]&.value; end
370
382
  # Gets the value of `peers` attribute in the message.
371
383
  #--
372
- # @rbs return: untyped
384
+ # @rbs return: ::Array[AttributeSets::Wgpeer]
373
385
  def peers; attributes[:"peers"]&.value; end
374
386
  end
375
387
  end
388
+ module Notifications
389
+ end
390
+ NOTIFICATIONS = Ractor.make_shareable({}) #: Hash[::Integer, ::Class]
376
391
  # Retrieve WireGuard device
377
392
  # ~~~~~~~~~~~~~~~~~~~~~~~~~
378
393
  #
@@ -397,6 +412,9 @@ class Wireguard < ::Nl::Family
397
412
  # be ``NLMSG_DONE``, even if an error occurs. However, this ``NLMSG_DONE``
398
413
  # message contains an integer error code. It is either zero or a negative
399
414
  # error code corresponding to the errno.
415
+ #
416
+ #
417
+ # Requires CAP_NET_ADMIN in the user namespace owning the network namespace.
400
418
  #--
401
419
  # @rbs (?ifindex: ::Integer, ?ifname: ::String) -> Enumerable[Messages::DumpGetDeviceReply]
402
420
  # | (?ifindex: ::Integer, ?ifname: ::String) { (Messages::DumpGetDeviceReply) -> void } -> void
@@ -421,10 +439,84 @@ class Wireguard < ::Nl::Family
421
439
  # subsequent fragments.
422
440
  #
423
441
  # If an error occurs, ``NLMSG_ERROR`` will reply containing an errno.
442
+ #
443
+ #
444
+ # Requires CAP_NET_ADMIN in the user namespace owning the network namespace.
424
445
  #--
425
- # @rbs (?ifindex: ::Integer, ?ifname: ::String, ?private_key: untyped, ?public_key: untyped, ?flags: ::Integer, ?listen_port: ::Integer, ?fwmark: ::Integer, ?peers: untyped) -> void
446
+ # @rbs (?ifindex: ::Integer, ?ifname: ::String, ?private_key: ::String, ?public_key: ::String, ?flags: ::Integer, ?listen_port: ::Integer, ?fwmark: ::Integer, ?peers: ::Array[AttributeSets::Wgpeer]) -> void
426
447
  def do_set_device(**args)
427
448
  exchange_message(:"do", Messages::DoSetDeviceRequest, nil, args)
428
449
  end
450
+ class AsyncOperations
451
+ # :nodoc:
452
+ def initialize(&exchange)
453
+ @exchange = exchange
454
+ end
455
+ # Retrieve WireGuard device
456
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~
457
+ #
458
+ # The command should be called with one but not both of:
459
+ #
460
+ # - ``WGDEVICE_A_IFINDEX``
461
+ # - ``WGDEVICE_A_IFNAME``
462
+ #
463
+ # The kernel will then return several messages (``NLM_F_MULTI``). It is
464
+ # possible that all of the allowed IPs of a single peer will not fit
465
+ # within a single netlink message. In that case, the same peer will be
466
+ # written in the following message, except it will only contain
467
+ # ``WGPEER_A_PUBLIC_KEY`` and ``WGPEER_A_ALLOWEDIPS``. This may occur
468
+ # several times in a row for the same peer. It is then up to the receiver
469
+ # to coalesce adjacent peers. Likewise, it is possible that all peers will
470
+ # not fit within a single message. So, subsequent peers will be sent in
471
+ # following messages, except those will only contain ``WGDEVICE_A_IFNAME``
472
+ # and ``WGDEVICE_A_PEERS``. It is then up to the receiver to coalesce
473
+ # these messages to form the complete list of peers.
474
+ #
475
+ # Since this is an ``NLA_F_DUMP`` command, the final message will always
476
+ # be ``NLMSG_DONE``, even if an error occurs. However, this ``NLMSG_DONE``
477
+ # message contains an integer error code. It is either zero or a negative
478
+ # error code corresponding to the errno.
479
+ #
480
+ #
481
+ # Requires CAP_NET_ADMIN in the user namespace owning the network namespace.
482
+ #--
483
+ # @rbs (?ifindex: ::Integer, ?ifname: ::String) -> ::Nl::Async::Stream[Messages::DumpGetDeviceReply]
484
+ def dump_get_device(**args)
485
+ @exchange.call(:"dump", Messages::DumpGetDeviceRequest, Messages::DumpGetDeviceReply, args)
486
+ end
487
+ # Set WireGuard device
488
+ # ~~~~~~~~~~~~~~~~~~~~
489
+ #
490
+ # This command should be called with a wgdevice set, containing one but
491
+ # not both of ``WGDEVICE_A_IFINDEX`` and ``WGDEVICE_A_IFNAME``.
492
+ #
493
+ # It is possible that the amount of configuration data exceeds that of the
494
+ # maximum message length accepted by the kernel. In that case, several
495
+ # messages should be sent one after another, with each successive one
496
+ # filling in information not contained in the prior. Note that if
497
+ # ``WGDEVICE_F_REPLACE_PEERS`` is specified in the first message, it
498
+ # probably should not be specified in fragments that come after, so that
499
+ # the list of peers is only cleared the first time but appended after.
500
+ # Likewise for peers, if ``WGPEER_F_REPLACE_ALLOWEDIPS`` is specified in
501
+ # the first message of a peer, it likely should not be specified in
502
+ # subsequent fragments.
503
+ #
504
+ # If an error occurs, ``NLMSG_ERROR`` will reply containing an errno.
505
+ #
506
+ #
507
+ # Requires CAP_NET_ADMIN in the user namespace owning the network namespace.
508
+ #--
509
+ # @rbs (?ifindex: ::Integer, ?ifname: ::String, ?private_key: ::String, ?public_key: ::String, ?flags: ::Integer, ?listen_port: ::Integer, ?fwmark: ::Integer, ?peers: ::Array[AttributeSets::Wgpeer]) -> ::Nl::Async::Future[void]
510
+ def do_set_device(**args)
511
+ @exchange.call(:"do", Messages::DoSetDeviceRequest, nil, args)
512
+ end
513
+ end
514
+ # Returns the asynchronous operation facade for this family.
515
+ #--
516
+ # @rbs (?stream_capacity: ::Integer?) -> AsyncOperations
517
+ def async(stream_capacity: nil)
518
+ return @async_operations ||= build_async_facade(AsyncOperations) if stream_capacity.nil?
519
+ build_async_facade(AsyncOperations, stream_capacity:)
520
+ end
429
521
  end
430
522
  end; end
@@ -1,5 +1,5 @@
1
1
  module Nl
2
2
  module Linux
3
- VERSION = '0.2.4'
3
+ VERSION = '0.3.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nl-linux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kasumi Hanazuki
@@ -15,35 +15,37 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.2.4
18
+ version: 0.3.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.2.4
25
+ version: 0.3.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: ynl
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.2.4
32
+ version: 0.3.0
33
33
  type: :development
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.2.4
40
- description: Linux Netlink client
39
+ version: 0.3.0
40
+ description: nl-linux is a collection of Netlink clients for Linux kernel APIs, generated
41
+ from the kernel's YAML specifications (YNL).
41
42
  email:
42
43
  - kasumi@rollingapple.net
43
44
  executables: []
44
45
  extensions: []
45
46
  extra_rdoc_files: []
46
47
  files:
48
+ - ".rspec"
47
49
  - CHANGELOG.md
48
50
  - NLSPEC_VERSION
49
51
  - README.md
@@ -125,7 +127,7 @@ licenses:
125
127
  - "(GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause"
126
128
  metadata:
127
129
  homepage_uri: https://github.com/hanazuki/nl
128
- source_code_uri: https://github.com/hanazuki/nl/tree/v0.2.4
130
+ source_code_uri: https://github.com/hanazuki/nl/tree/v0.3.0
129
131
  changelog_uri: https://github.com/hanazuki/nl/blob/master/CHANGELOG.md
130
132
  rdoc_options: []
131
133
  require_paths:
@@ -135,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
137
  requirements:
136
138
  - - ">="
137
139
  - !ruby/object:Gem::Version
138
- version: '3.1'
140
+ version: '3.4'
139
141
  required_rubygems_version: !ruby/object:Gem::Requirement
140
142
  requirements:
141
143
  - - ">="
@@ -144,5 +146,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
146
  requirements: []
145
147
  rubygems_version: 4.0.6
146
148
  specification_version: 4
147
- summary: Linux Netlink client
149
+ summary: Clients for Linux kernel Netlink API
148
150
  test_files: []