Add addr high-level API
Makefile.am
12 | 12 | netlink/route/attrs.scm \ | |
13 | 13 | netlink/route/link.scm \ | |
14 | 14 | netlink/route/route.scm \ | |
15 | - | ip/link.scm | |
15 | + | ip/addr.scm \ | |
16 | + | ip/link.scm \ | |
17 | + | ip/utils.scm | |
16 | 18 | ||
17 | 19 | info_TEXINFOS= doc/guile-netlink.texi |
doc/guile-netlink.texi
533 | 533 | or its index, as a number. | |
534 | 534 | @end deffn | |
535 | 535 | ||
536 | + | @node Addr | |
537 | + | @section Addr | |
538 | + | ||
539 | + | The @code{(ip addr)} module introduces procedures to access and modify the | |
540 | + | network addresses on your machine. They are equivalent to the @command{ip addr} | |
541 | + | family of commands, from @code{iproute2}. | |
542 | + | ||
543 | + | @deffn {Scheme Procedure} addr-del @var{device} @var{cidr} [@var{#:ipv6?} #f] | |
544 | + | Delete the address given in @var{cidr} from @var{device}. @var{device} can | |
545 | + | contain the name of the link, as a string, or its index, as a number. | |
546 | + | ||
547 | + | @var{cidr} must be a string containing the address and prefix length, in | |
548 | + | CIDR notation (@code{addr/prefix}). | |
549 | + | ||
550 | + | @example | |
551 | + | (addr-del "enp1s0" "192.0.2.15/24") | |
552 | + | @end example | |
553 | + | ||
554 | + | If you wish to remove an IPv6 address instead, set @code{#:ipv6} to @code{#t}, | |
555 | + | as in the following example. | |
556 | + | ||
557 | + | @example | |
558 | + | (addr-del "enp1s0" "2001:db8::1a4c/64" #:ipv6? #t) | |
559 | + | @end example | |
560 | + | ||
561 | + | Note that using the wrong ip type with the wrong value for the @code{#:ipv6?} | |
562 | + | flag will result in a @code{Bad address} error from netlink. | |
563 | + | @end deffn | |
564 | + | ||
536 | 565 | @bye |
ip/addr.scm unknown status 1
1 | + | ;;;; Copyright (C) 2021 Julien Lepiller <julien@lepiller.eu> | |
2 | + | ;;;; | |
3 | + | ;;;; This library is free software; you can redistribute it and/or | |
4 | + | ;;;; modify it under the terms of the GNU Lesser General Public | |
5 | + | ;;;; License as published by the Free Software Foundation; either | |
6 | + | ;;;; version 3 of the License, or (at your option) any later version. | |
7 | + | ;;;; | |
8 | + | ;;;; This library is distributed in the hope that it will be useful, | |
9 | + | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | + | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | + | ;;;; Lesser General Public License for more details. | |
12 | + | ;;;; | |
13 | + | ;;;; You should have received a copy of the GNU Lesser General Public | |
14 | + | ;;;; License along with this library; if not, write to the Free Software | |
15 | + | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
16 | + | ;;;; | |
17 | + | ||
18 | + | (define-module (ip addr) | |
19 | + | #:use-module (ice-9 match) | |
20 | + | #:use-module (ip link) | |
21 | + | #:use-module (ip utils) | |
22 | + | #:use-module (netlink route addr) | |
23 | + | #:use-module (netlink route attrs) | |
24 | + | #:use-module (netlink connection) | |
25 | + | #:use-module (netlink constant) | |
26 | + | #:use-module (netlink deserialize) | |
27 | + | #:use-module (netlink message) | |
28 | + | #:use-module (netlink standard) | |
29 | + | #:use-module (srfi srfi-1) | |
30 | + | #:export (addr-add | |
31 | + | addr-del | |
32 | + | addr-show)) | |
33 | + | ||
34 | + | (define (cidr->addr str) | |
35 | + | (match (string-split str #\/) | |
36 | + | ((addr) addr) | |
37 | + | ((addr prefix) addr) | |
38 | + | (_ (throw 'incorrect-cidr-notation str)))) | |
39 | + | ||
40 | + | (define (cidr->prefix str) | |
41 | + | (match (string-split str #\/) | |
42 | + | ((addr) #f) | |
43 | + | ((addr prefix) (string->number prefix)) | |
44 | + | (_ (throw 'incorrect-cidr-notation str)))) | |
45 | + | ||
46 | + | (define* (addr-del device cidr #:key (ipv6? #f)) | |
47 | + | (define request-num (random 65535)) | |
48 | + | (define prefix (cidr->prefix cidr)) | |
49 | + | (define addr (cidr->addr cidr)) | |
50 | + | ||
51 | + | (define index | |
52 | + | (cond | |
53 | + | ((number? device) device) | |
54 | + | ((string? device) (link-name->index device)))) | |
55 | + | ||
56 | + | (define message | |
57 | + | (make-message | |
58 | + | RTM_DELADDR | |
59 | + | (logior NLM_F_REQUEST NLM_F_ACK) | |
60 | + | request-num | |
61 | + | 0 | |
62 | + | (make-addr-message | |
63 | + | (if ipv6? AF_INET6 AF_INET) | |
64 | + | (if prefix prefix 0) | |
65 | + | 0 | |
66 | + | 0 | |
67 | + | index | |
68 | + | (list | |
69 | + | (make-route-attr IFA_LOCAL | |
70 | + | ((if ipv6? | |
71 | + | make-ipv6-route-attr | |
72 | + | make-ipv4-route-attr) | |
73 | + | addr)) | |
74 | + | (make-route-attr IFA_ADDRESS | |
75 | + | ((if ipv6? | |
76 | + | make-ipv6-route-attr | |
77 | + | make-ipv4-route-attr) | |
78 | + | addr)))))) | |
79 | + | ||
80 | + | (let ((sock (connect-route))) | |
81 | + | (send-msg message sock) | |
82 | + | (let ((answer (receive-and-decode-msg sock %default-route-decoder))) | |
83 | + | (close-socket sock) | |
84 | + | (answer-ok? (last answer))))) |
ip/link.scm
17 | 17 | ||
18 | 18 | (define-module (ip link) | |
19 | 19 | #:use-module (ice-9 match) | |
20 | + | #:use-module (ip utils) | |
20 | 21 | #:use-module (netlink route attrs) | |
21 | 22 | #:use-module (netlink route link) | |
22 | 23 | #:use-module (netlink connection) | |
… | |||
30 | 31 | #:export (link-add | |
31 | 32 | link-del | |
32 | 33 | link-set | |
33 | - | link-show)) | |
34 | + | link-show | |
35 | + | link-name->index)) | |
34 | 36 | ||
35 | 37 | (define-record-type <link> | |
36 | 38 | (make-link name id type flags mtu qdisc state mode group qlen addr brd) | |
… | |||
165 | 167 | (link-id link) | |
166 | 168 | (loop links)))))) | |
167 | 169 | ||
168 | - | (define (answer-ok? answer) | |
169 | - | (cond | |
170 | - | ((equal? (message-kind answer) NLMSG_DONE) | |
171 | - | #t) | |
172 | - | ((equal? (message-kind answer) NLMSG_ERROR) | |
173 | - | (let ((data (message-data answer))) | |
174 | - | (if (nl-data-data data) | |
175 | - | (let ((err (error-message-err data))) | |
176 | - | (if (equal? err 0) | |
177 | - | #t | |
178 | - | (begin | |
179 | - | (format #t "RTNETLINK answers: ~a~%" (strerror (- err))) | |
180 | - | #f))) | |
181 | - | #f))))) | |
182 | - | ||
183 | 170 | (define* (link-set device #:key (up #f) (down #f) (type #f) | |
184 | 171 | (arp-on #f) (arp-off #f) | |
185 | 172 | (dynamic-on #f) (dynamic-off #f) |
ip/utils.scm unknown status 1
1 | + | ;;;; Copyright (C) 2021 Julien Lepiller <julien@lepiller.eu> | |
2 | + | ;;;; | |
3 | + | ;;;; This library is free software; you can redistribute it and/or | |
4 | + | ;;;; modify it under the terms of the GNU Lesser General Public | |
5 | + | ;;;; License as published by the Free Software Foundation; either | |
6 | + | ;;;; version 3 of the License, or (at your option) any later version. | |
7 | + | ;;;; | |
8 | + | ;;;; This library is distributed in the hope that it will be useful, | |
9 | + | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | + | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | + | ;;;; Lesser General Public License for more details. | |
12 | + | ;;;; | |
13 | + | ;;;; You should have received a copy of the GNU Lesser General Public | |
14 | + | ;;;; License along with this library; if not, write to the Free Software | |
15 | + | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
16 | + | ;;;; | |
17 | + | ||
18 | + | (define-module (ip utils) | |
19 | + | #:use-module (netlink constant) | |
20 | + | #:use-module (netlink data) | |
21 | + | #:use-module (netlink message) | |
22 | + | #:use-module (netlink standard) | |
23 | + | #:export (answer-ok?)) | |
24 | + | ||
25 | + | (define (answer-ok? answer) | |
26 | + | (cond | |
27 | + | ((equal? (message-kind answer) NLMSG_DONE) | |
28 | + | #t) | |
29 | + | ((equal? (message-kind answer) NLMSG_ERROR) | |
30 | + | (let ((data (message-data answer))) | |
31 | + | (if (nl-data-data data) | |
32 | + | (let ((err (error-message-err data))) | |
33 | + | (if (equal? err 0) | |
34 | + | #t | |
35 | + | (begin | |
36 | + | (format #t "RTNETLINK answers: ~a~%" (strerror (- err))) | |
37 | + | #f))) | |
38 | + | #f))))) |