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) |