connection: Add 'add-socket-membership'. * netlink/connection.scm (socklen_t, ffi-setsockopt, SOL_NETLINK) * netlink/connection.scm (NETLINK_ADD_MEMBERSHIP) (NETLINK_DROP_MEMBERSHIP, NETLINK_PKTINFO) (NETLINK_BROADCAST_ERROR, NETLINK_NO_ENOBUFS) (NETLINK_LISTEN_ALL_NSID, NETLINK_LIST_MEMBERSHIPS) (NETLINK_CAP_ACK, NETLINK_EXT_ACK, NETLINK_GET_STRICT_CHK): New variables. (add-socket-membership): New procedure. * netlink/constant.scm (int->rtnetlink-group): New enum. * doc/guile-netlink.texi (Netlink Connections): Document it. Signed-off-by: Julien Lepiller <julien@lepiller.eu>
doc/guile-netlink.texi
263 | 263 | to the @code{socket} system call---e.g., @code{SOCK_NONBLOCK}. | |
264 | 264 | @end deffn | |
265 | 265 | ||
266 | + | @cindex subscribing, to an rtnetlink group | |
267 | + | @deffn {Scheme Procedure} add-socket-membership @var{sock} @var{group} | |
268 | + | Make @var{sock} a member of @var{group}, an @code{RTNLGRP_} constant, | |
269 | + | meaning that it will be subscribed to events of that group. | |
270 | + | ||
271 | + | For example, here is how you could create a netlink socket and subscribe | |
272 | + | it to the ``link'' group so that it receives notifications for new and | |
273 | + | removed links: | |
274 | + | ||
275 | + | @lisp | |
276 | + | (let ((sock (connect-route))) | |
277 | + | (add-socket-membership sock RTNLGRP_LINK) | |
278 | + | @dots{}) | |
279 | + | @end lisp | |
280 | + | ||
281 | + | This procedure is implemented as a @code{setsockopt} call. | |
282 | + | @end deffn | |
283 | + | ||
266 | 284 | @deffn {Scheme Procedure} send-msg @var{msg} @var{sock} [#:@var{addr}] | |
267 | 285 | Send @var{msg} (it must be of type message, @xref{Netlink Headers}) to | |
268 | 286 | @var{addr} using @var{sock}. If not passed, @var{addr} is the address of |
netlink/connection.scm
30 | 30 | current-write-waiter) | |
31 | 31 | #:export (connect | |
32 | 32 | connect-route | |
33 | + | add-socket-membership | |
33 | 34 | close-socket | |
34 | 35 | send-msg | |
35 | 36 | receive-msg | |
… | |||
73 | 74 | (syscall->procedure int "bind" (list int '* int) | |
74 | 75 | #:waiter (lambda () (current-read-waiter)))) | |
75 | 76 | ||
77 | + | (define socklen_t uint32) ;per <posix/bits/types.h> | |
78 | + | (define ffi-setsockopt | |
79 | + | (syscall->procedure int "setsockopt" (list int int int '* socklen_t))) | |
80 | + | ||
81 | + | (define SOL_NETLINK 270) | |
82 | + | ||
83 | + | (define NETLINK_ADD_MEMBERSHIP 1) | |
84 | + | (define NETLINK_DROP_MEMBERSHIP 2) | |
85 | + | (define NETLINK_PKTINFO 3) | |
86 | + | (define NETLINK_BROADCAST_ERROR 4) | |
87 | + | (define NETLINK_NO_ENOBUFS 5) | |
88 | + | (define NETLINK_LISTEN_ALL_NSID 8) | |
89 | + | (define NETLINK_LIST_MEMBERSHIPS 9) | |
90 | + | (define NETLINK_CAP_ACK 10) | |
91 | + | (define NETLINK_EXT_ACK 11) | |
92 | + | (define NETLINK_GET_STRICT_CHK 12) | |
93 | + | ||
76 | 94 | ;; define simple functions to open/close sockets | |
77 | 95 | (define (open-socket proto flags) | |
78 | 96 | (socket AF_NETLINK (logior SOCK_RAW SOCK_CLOEXEC flags) proto)) | |
79 | 97 | ||
98 | + | (define (add-socket-membership sock group) | |
99 | + | "Make @var{sock} a member of @var{group}, an @code{RTNLGRP_} constant, | |
100 | + | meaning that it will be subscribed to events of that group." | |
101 | + | (let ((bv (make-bytevector (sizeof int)))) | |
102 | + | (bytevector-uint-set! bv 0 group (native-endianness) (sizeof int)) | |
103 | + | (ffi-setsockopt sock SOL_NETLINK NETLINK_ADD_MEMBERSHIP | |
104 | + | (bytevector->pointer bv) (bytevector-length bv)))) | |
105 | + | ||
80 | 106 | (define (close-socket sock) | |
81 | 107 | (issue-deprecation-warning | |
82 | 108 | "'close-socket' is deprecated; use 'close-port' instead.") |
netlink/constant.scm
345 | 345 | (define-enum int->link-type | |
346 | 346 | (ARPHRD_ETHER 1) | |
347 | 347 | (ARPHRD_LOOPBACK 772)) | |
348 | + | ||
349 | + | ;; enum rtnetlink_groups | |
350 | + | (define-enum int->rtnetlink-group | |
351 | + | (RTNLGRP_NONE 0) | |
352 | + | RTNLGRP_LINK | |
353 | + | RTNLGRP_NOTIFY | |
354 | + | RTNLGRP_NEIGH | |
355 | + | RTNLGRP_TC | |
356 | + | RTNLGRP_IPV4_IFADDR | |
357 | + | RTNLGRP_IPV4_MROUTE | |
358 | + | RTNLGRP_IPV4_ROUTE | |
359 | + | RTNLGRP_IPV4_RULE | |
360 | + | RTNLGRP_IPV6_IFADDR | |
361 | + | RTNLGRP_IPV6_MROUTE | |
362 | + | RTNLGRP_IPV6_ROUTE | |
363 | + | RTNLGRP_IPV6_IFINFO | |
364 | + | RTNLGRP_DECnet_IFADDR | |
365 | + | RTNLGRP_NOP2 | |
366 | + | RTNLGRP_DECnet_ROUTE | |
367 | + | RTNLGRP_DECnet_RULE | |
368 | + | RTNLGRP_NOP4 | |
369 | + | RTNLGRP_IPV6_PREFIX | |
370 | + | RTNLGRP_IPV6_RULE | |
371 | + | RTNLGRP_ND_USEROPT | |
372 | + | RTNLGRP_PHONET_IFADDR | |
373 | + | RTNLGRP_PHONET_ROUTE | |
374 | + | RTNLGRP_DCB | |
375 | + | RTNLGRP_IPV4_NETCONF | |
376 | + | RTNLGRP_IPV6_NETCONF | |
377 | + | RTNLGRP_MDB | |
378 | + | RTNLGRP_MPLS_ROUTE | |
379 | + | RTNLGRP_NSID | |
380 | + | RTNLGRP_MPLS_NETCONF | |
381 | + | RTNLGRP_IPV4_MROUTE_R | |
382 | + | RTNLGRP_IPV6_MROUTE_R | |
383 | + | RTNLGRP_NEXTHOP | |
384 | + | RTNLGRP_BRVLAN | |
385 | + | RTNLGRP_MCTP_IFADDR | |
386 | + | RTNLGRP_TUNNEL | |
387 | + | RTNLGRP_STATS) |