Add addr high-level API

Julien LepillerSat Mar 13 22:48:03+0100 2021

108be91

Add addr high-level API

Makefile.am

1212
  netlink/route/attrs.scm \
1313
  netlink/route/link.scm \
1414
  netlink/route/route.scm \
15-
  ip/link.scm
15+
  ip/addr.scm \
16+
  ip/link.scm \
17+
  ip/utils.scm
1618
1719
info_TEXINFOS= doc/guile-netlink.texi

doc/guile-netlink.texi

533533
or its index, as a number.
534534
@end deffn
535535
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+
536565
@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

1717
1818
(define-module (ip link)
1919
  #:use-module (ice-9 match)
20+
  #:use-module (ip utils)
2021
  #:use-module (netlink route attrs)
2122
  #:use-module (netlink route link)
2223
  #:use-module (netlink connection)

3031
  #:export (link-add
3132
            link-del
3233
            link-set
33-
            link-show))
34+
            link-show
35+
            link-name->index))
3436
3537
(define-record-type <link>
3638
  (make-link name id type flags mtu qdisc state mode group qlen addr brd)

165167
           (link-id link)
166168
           (loop links))))))
167169
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-
183170
(define* (link-set device #:key (up #f) (down #f) (type #f)
184171
                   (arp-on #f) (arp-off #f)
185172
                   (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)))))