Add more flags to (ip addr) procedures

Julien LepillerSat Dec 25 16:22:28+0100 2021

b7aa2be

Add more flags to (ip addr) procedures

doc/guile-netlink.texi

605605
network addresses on your machine.  They are equivalent to the @command{ip addr}
606606
family of commands, from @code{iproute2}.
607607
608-
@deffn {Scheme Procedure} addr-add @var{device} @var{cidr} [@var{#:ipv6?} #f]
608+
@deffn {Scheme Procedure} addr-add @var{device} @var{cidr} [@var{#:ipv6?} #f] @
609+
        [@var{#:peer} @code{(cidr->addr cidr)}] [@var{#:broadcast} #f] @
610+
        [@var{#:anycast} #f] [@var{#:label} #f] [@var{#:scope} @code{'global}] @
611+
        [@var{#:metric} #f] [@var{#:home?} #f] [@var{#:mngtmpaddr?} #f] @
612+
        [@var{#:nodad?} #f] [@var{optimistic?} #f] [@var{noprefixroute?} #f] @
613+
        [@var{#:autojoin?} #f]
609614
Add the address given in @var{cidr} to @var{device}. @var{device} can
610615
contain the name of the link, as a string, or its index, as a number.
611616

625630
626631
Note that using the wrong ip type with the wrong value for the @code{#:ipv6?}
627632
flag will result in a @code{Bad address} exception from inet-pton.
633+
634+
Additional flags are available; they follow the same semantics as Iproute2.
635+
For pointopoint interfaces, you can specify the address of the remote endpoint
636+
with @var{#:peer}. You can specify a broadcast or anycast address with
637+
@var{#:broadcast} and @var{#:anycast}. All three require an IP address passed
638+
as a string when specified.
639+
640+
You can specify a label for the address with @var{#:label}. The parameter must
641+
be a string that is either the name of the device, or starts with the name of
642+
the device, followed by a colon and must contain at most 15 characters.
643+
644+
You can specify a scope with @var{#:scope}, whose value is either @code{'global},
645+
@code{'link}, @code{'host} or a numeric value.
646+
647+
You can specify the priority of the prefix route associated with this address
648+
using @code{#:metric}, a number.
649+
650+
Finally, this procedures accepts address configuration flags, whose values are
651+
booleans.  They are unset by default.  Some flags only work for IPv6 addresses,
652+
those are @var{#:home?} to designate this address as the ``home address'',
653+
@var{#:mngtmpaddr?}, @var{#:nodad?} and @var{#:optimistic?}. The flags
654+
@var{#:noprefixroute?} and @var{#:autojoin?} can be set for IPv4 and IPv6
655+
addresses.
628656
@end deffn
629657
630-
@deffn {Scheme Procedure} addr-del @var{device} @var{cidr} [@var{#:ipv6?} #f]
658+
@deffn {Scheme Procedure} addr-del @var{device} @var{cidr} [@var{#:ipv6?} #f] @
659+
        [@var{#:peer} @code{(cidr->addr cidr)}] [@var{#:broadcast} #f] @
660+
        [@var{#:anycast} #f] [@var{#:label} #f] [@var{#:scope} @code{'global}] @
661+
        [@var{#:metric} #f] [@var{#:home?} #f] [@var{#:mngtmpaddr?} #f] @
662+
        [@var{#:nodad?} #f] [@var{optimistic?} #f] [@var{noprefixroute?} #f] @
663+
        [@var{#:autojoin?} #f]
631664
Delete the address given in @var{cidr} from @var{device}. @var{device} can
632665
contain the name of the link, as a string, or its index, as a number.
633666

647680
648681
Note that using the wrong ip type with the wrong value for the @code{#:ipv6?}
649682
flag will result in a @code{Bad address} exception from inet-pton.
683+
684+
Additional flags are available, see the description in @code{addr-add} for more
685+
details.
650686
@end deffn
651687
652688
@deffn {Scheme Procedure} addr-show [@var{device}]

ip/addr.scm

4545
  (brd       addr-brd)
4646
  (cacheinfo addr-cacheinfo))
4747
48-
(define* (addr-del device cidr #:key (ipv6? #f) (peer (cidr->addr cidr)))
48+
(define* (addr-del device cidr #:key (ipv6? #f) (peer (cidr->addr cidr))
49+
                   (broadcast #f) (anycast #f)
50+
                   (label #f) (scope 'global) (metric #f)
51+
                   (home? #f) (mngtmpaddr? #f) (nodad? #f) (optimistic? #f)
52+
                   (noprefixroute? #f) (autojoin? #f))
4953
  (define request-num (random 65535))
5054
  (define prefix (cidr->prefix cidr))
5155
  (define addr (cidr->addr cidr))

5559
      ((number? device) device)
5660
      ((string? device) (link-name->index device))))
5761
62+
  (define scope-num
63+
    (match scope
64+
      ((? number? scope) scope)
65+
      ('global RT_SCOPE_UNIVERSE)
66+
      ('host RT_SCOPE_HOST)
67+
      ('link RT_SCOPE_LINK)))
68+
69+
  (define ifa-flags
70+
    (logior (if (and ipv6? mngtmpaddr?) IFA_F_MANAGETEMPADDR 0)
71+
            (if noprefixroute? IFA_F_NOPREFIXROUTE 0)
72+
            (if autojoin? IFA_F_MCAUTOJOIN 0)))
73+
5874
  (define message
5975
    (make-message
6076
      RTM_DELADDR

6480
      (make-addr-message
6581
        (if ipv6? AF_INET6 AF_INET)
6682
        (if prefix prefix 0)
67-
        0
68-
        0
83+
        (logior (if (and ipv6? home?) IFA_F_HOMEADDRESS 0)
84+
                (if (and ipv6? nodad?) IFA_F_NODAD 0)
85+
                (if (and ipv6? optimistic?) IFA_F_OPTIMISTIC 0))
86+
        scope-num
6987
        index
7088
        (list
7189
          (make-route-attr IFA_LOCAL

85103
      (close-socket sock)
86104
      (answer-ok? (last answer)))))
87105
88-
(define* (addr-add device cidr #:key (ipv6? #f) (peer (cidr->addr cidr)))
106+
(define* (addr-add device cidr #:key (ipv6? #f) (peer (cidr->addr cidr))
107+
                   (broadcast #f) (anycast #f)
108+
                   (label #f) (scope 'global) (metric #f)
109+
                   (home? #f) (mngtmpaddr? #f) (nodad? #f) (optimistic? #f)
110+
                   (noprefixroute? #f) (autojoin? #f))
89111
  (define request-num (random 65535))
90112
  (define prefix (cidr->prefix cidr))
91113
  (define addr (cidr->addr cidr))

95117
      ((number? device) device)
96118
      ((string? device) (link-name->index device))))
97119
120+
  (define scope-num
121+
    (match scope
122+
      ((? number? scope) scope)
123+
      ('global RT_SCOPE_UNIVERSE)
124+
      ('host RT_SCOPE_HOST)
125+
      ('link RT_SCOPE_LINK)))
126+
127+
  (define ifa-flags
128+
    (logior (if (and ipv6? mngtmpaddr?) IFA_F_MANAGETEMPADDR 0)
129+
            (if noprefixroute? IFA_F_NOPREFIXROUTE 0)
130+
            (if autojoin? IFA_F_MCAUTOJOIN 0)))
131+
98132
  (define message
99133
    (make-message
100134
      RTM_NEWADDR

104138
      (make-addr-message
105139
        (if ipv6? AF_INET6 AF_INET)
106140
        (if prefix prefix 0)
107-
        0
108-
        0
141+
        (logior (if (and ipv6? home?) IFA_F_HOMEADDRESS 0)
142+
                (if (and ipv6? nodad?) IFA_F_NODAD 0)
143+
                (if (and ipv6? optimistic?) IFA_F_OPTIMISTIC 0))
144+
        scope-num
109145
        index
110-
        (list
111-
          (make-route-attr IFA_LOCAL
146+
        `(,(make-route-attr IFA_LOCAL
112147
            ((if ipv6?
113148
                 make-ipv6-route-attr
114149
                 make-ipv4-route-attr)
115150
             addr))
116-
          (make-route-attr IFA_ADDRESS
151+
          ,(make-route-attr IFA_ADDRESS
117152
            ((if ipv6?
118153
                 make-ipv6-route-attr
119154
                 make-ipv4-route-attr)
120-
             peer))))))
155+
             peer))
156+
          ,@(if broadcast
157+
                `((,(make-route-attr IFA_BROADCAST
158+
                      ((if ipv6?
159+
                           make-ipv6-route-attr
160+
                           make-ipv4-route-attr)
161+
                       broadcast))))
162+
                '())
163+
          ,@(if anycast
164+
                `((,(make-route-attr IFA_ANYCAST
165+
                      ((if ipv6?
166+
                           make-ipv6-route-attr
167+
                           make-ipv4-route-attr)
168+
                       anycast))))
169+
                '())
170+
          ,@(if (> ifa-flags 0)
171+
                `((,(make-route-attr IFA_FLAGS (make-u32-route-attr ifa-flags))))
172+
                '())
173+
          ,@(if label
174+
                `((,(make-route-attr IFA_LABEL (make-string-route-attr label))))
175+
                '())
176+
          ,@(if metric
177+
                `((,(make-route-attr IFA_RT_PRIORITY (make-u32-route-attr metric))))
178+
                '())))))
121179
122180
  (let ((sock (connect-route)))
123181
    (send-msg message sock)

netlink/route/attrs.scm

292292
    (,IFA_ANYCAST . ,address-decoder)
293293
    (,IFA_FLAGS . ,deserialize-route-attr-data-u32)
294294
    (,IFA_CACHEINFO . ,deserialize-route-attr-data-route-cache-info)
295+
    (,IFA_RT_PRIORITY . ,deserialize-route-attr-data-u32)
295296
    (default . ,deserialize-route-attr-data-bv)))
296297
297298
(define (default-route-route-attr-decoder address-decoder)