guile-netlink/netlink/route/attrs.scm

attrs.scm

1
;;;; This file is part of Guile Netlink
2
;;;;
3
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
4
;;;; 
5
;;;; This library is free software: you can redistribute it and/or modify
6
;;;; it under the terms of the GNU General Public License as published by
7
;;;; the Free Software Foundation, either version 3 of the License, or
8
;;;; (at your option) any later version.
9
;;;;
10
;;;; This library is distributed in the hope that it will be useful,
11
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
;;;; GNU General Public License for more details.
14
;;;;
15
;;;; You should have received a copy of the GNU General Public License
16
;;;; along with this library.  If not, see <https://www.gnu.org/licenses/>.
17
18
(define-module (netlink route attrs)
19
  #:use-module (ice-9 match)
20
  #:use-module (netlink constant)
21
  #:use-module (netlink data)
22
  #:use-module (netlink route)
23
  #:use-module (rnrs bytevectors)
24
  #:use-module (srfi srfi-9)
25
  #:export(deserialize-attr-list
26
           make-route-attr
27
           route-attr?
28
           route-attr-kind
29
           route-attr-data
30
           route-attr-size
31
           make-route-cache-info-attr
32
           route-cache-info-attr?
33
           route-cache-info-attr-prefered
34
           route-cache-info-attr-valid
35
           route-cache-info-attr-cstamp
36
           route-cache-info-attr-tstamp
37
           route-cache-info-attr-type-prefered
38
           route-cache-info-attr-type-valid
39
           route-cache-info-attr-type-cstamp
40
           route-cache-info-attr-type-tstamp
41
           make-u8-route-attr
42
           make-u16-route-attr
43
           make-u32-route-attr
44
           make-s32-route-attr
45
           make-nested-route-attr
46
           make-string-route-attr
47
           make-ethernet-route-attr
48
           make-ipv4-route-attr
49
           make-ipv6-route-attr
50
           make-addr-cache-info-attr
51
           make-bv-route-attr
52
           deserialize-route-attr
53
           deserialize-route-attr-data-u8
54
           deserialize-route-attr-data-u16
55
           deserialize-route-attr-data-u32
56
           deserialize-route-attr-data-s32
57
           deserialize-route-attr-data-nested
58
           deserialize-route-attr-data-string
59
           deserialize-route-attr-data-ethernet
60
           deserialize-route-attr-data-ipv4
61
           deserialize-route-attr-data-ipv6
62
           deserialize-route-attr-data-route-cache-info
63
           deserialize-route-attr-data-bv
64
           %default-route-addr-ipv4-attr-decoder
65
           %default-route-addr-ipv6-attr-decoder
66
           %default-route-link-attr-decoder
67
           %default-route-link-info-attr-decoder
68
           %default-route-route-ipv4-attr-decoder
69
           %default-route-route-ipv6-attr-decoder))
70
71
(define (deserialize-attr-list context decoder bv pos)
72
  (let ((len (bytevector-length bv)))
73
    (let loop ((pos pos) (attrs '()))
74
      (if (>= pos len)
75
          attrs
76
          (let ((attr (deserialize context decoder bv pos)))
77
            (loop (+ pos (align (data-size attr) 4))
78
                  (cons attr attrs)))))))
79
80
(define-data-type route-attr
81
  attr-type-size
82
  (lambda (attr pos bv)
83
    (match attr
84
      (($ route-attr-type type data)
85
       (bytevector-u16-set! bv pos (attr-type-size attr) (native-endianness))
86
       (bytevector-u16-set! bv (+ pos 2) type (native-endianness))
87
       (serialize data (+ pos 4) bv))))
88
  (type route-attr-kind route-attr-type-type)
89
  (data route-attr-data route-attr-type-data))
90
91
(define (attr-type-size attr)
92
  (+ 4 (data-size (route-attr-type-data attr))))
93
94
(define-data-type route-cache-info-attr
95
  (const 16)
96
  (lambda (attr pos bv)
97
    (match attr
98
      (($ route-cache-info-attr-type prefered valid cstamp tstamp)
99
       (bytevector-u32-set! bv pos prefered (native-endianness))
100
       (bytevector-u32-set! bv (+ pos 4) valid (native-endianness))
101
       (bytevector-u32-set! bv (+ pos 8) cstamp (native-endianness))
102
       (bytevector-u32-set! bv (+ pos 12) tstamp (native-endianness)))))
103
  (prefered route-cache-info-attr-prefered route-cache-info-attr-type-prefered)
104
  (valid route-cache-info-attr-valid route-cache-info-attr-type-valid)
105
  (cstamp route-cache-info-attr-cstamp route-cache-info-attr-type-cstamp)
106
  (tstamp route-cache-info-attr-tstamp route-cache-info-attr-type-tstamp))
107
108
(define (make-u8-route-attr num)
109
  (make-nl-data
110
    num
111
    (const 1)
112
    (lambda (data pos bv)
113
      (bytevector-u8-set! bv pos data))))
114
115
(define (make-u16-route-attr num)
116
  (make-nl-data
117
    num
118
    (const 2)
119
    (lambda (data pos bv)
120
      (bytevector-u16-set! bv pos data (native-endianness)))))
121
122
(define (make-u32-route-attr num)
123
  (make-nl-data
124
    num
125
    (const 4)
126
    (lambda (data pos bv)
127
      (bytevector-u32-set! bv pos data (native-endianness)))))
128
129
(define (make-s32-route-attr num)
130
  (make-nl-data
131
    num
132
    (const 4)
133
    (lambda (data pos bv)
134
      (bytevector-s32-set! bv pos data (native-endianness)))))
135
136
(define (make-nested-route-attr lst)
137
  (make-nl-data
138
    lst
139
    route-attr-list-size
140
    serialize-route-attr-list))
141
142
(define (make-string-route-attr str)
143
  (make-nl-data
144
    str
145
    (lambda (str) (bytevector-length (string->utf8 str)))
146
    (lambda (data pos bv)
147
      (let ((s (string->utf8 data)))
148
        (bytevector-copy! s 0 bv pos (bytevector-length s))))))
149
150
(define (ethernet->bv addr)
151
  (u8-list->bytevector (map (lambda (n) (string->number n 16))
152
                            (string-split addr #\:))))
153
(define (make-ethernet-route-attr addr)
154
  (make-nl-data
155
    addr
156
    (lambda (addr) (bytevector-length (ethernet->bv addr)))
157
    (lambda (data pos bv)
158
      (let ((a (ethernet->bv data)))
159
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
160
161
(define (ipv4->bv addr)
162
  (u8-list->bytevector (map (lambda (n) (string->number n))
163
                            (string-split addr #\.))))
164
(define (make-ipv4-route-attr addr)
165
  (make-nl-data
166
    addr
167
    (lambda (addr) (bytevector-length (ipv4->bv addr)))
168
    (lambda (data pos bv)
169
      (let ((a (ipv4->bv data)))
170
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
171
172
;16 bytes
173
(define (ipv6->bv addr)
174
  (let loop ((num (inet-pton AF_INET6 addr)) (lst '()))
175
    (match lst
176
      ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)
177
       (u8-list->bytevector lst))
178
      (_
179
       (loop (quotient num 256) (cons (modulo num 256) lst))))))
180
(define (make-ipv6-route-attr addr)
181
  (make-nl-data
182
    addr
183
    (lambda (addr) (bytevector-length (ipv6->bv addr)))
184
    (lambda (data pos bv)
185
      (let ((a (ipv6->bv data)))
186
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
187
188
(define (make-bv-route-attr bv)
189
  (make-nl-data
190
    bv
191
    (lambda (bv) (bytevector-length bv))
192
    (lambda (data pos bv)
193
      (bytevector-copy! data 0 bv pos (bytevector-length data)))))
194
195
(define (deserialize-route-attr message-type)
196
  (lambda (decoder bv pos)
197
    (let* ((len (bytevector-u16-ref bv pos (native-endianness)))
198
           (type (bytevector-u16-ref bv (+ pos 2) (native-endianness)))
199
           (deserialize (get-next-deserialize decoder message-type type)))
200
      (if (= len 0)
201
          (let ((data-bv (make-bytevector 0)))
202
            (make-route-attr type (deserialize decoder data-bv 0)))
203
          (let ((data-bv (make-bytevector (- len 4))))
204
            (bytevector-copy! bv (+ pos 4) data-bv 0 (- len 4))
205
            (make-route-attr
206
              type
207
              (deserialize decoder data-bv 0)))))))
208
209
(define (deserialize-route-attr-data-nested attr-type)
210
  (lambda (decoder bv pos)
211
    (make-nested-route-attr
212
      (deserialize-attr-list attr-type decoder bv pos))))
213
214
(define (deserialize-route-attr-data-string decoder bv pos)
215
  (make-string-route-attr
216
    (or (false-if-exception (string-trim-right (utf8->string bv) #\nul))
217
        (make-string (bytevector-length bv) #\a))))
218
219
(define (deserialize-route-attr-data-u32 decoder bv pos)
220
  (make-u32-route-attr (bytevector-u32-ref bv pos (native-endianness))))
221
222
(define (deserialize-route-attr-data-s32 decoder bv pos)
223
  (make-s32-route-attr (bytevector-s32-ref bv pos (native-endianness))))
224
225
(define (deserialize-route-attr-data-u16 decoder bv pos)
226
  (make-u32-route-attr (bytevector-u16-ref bv pos (native-endianness))))
227
228
(define (deserialize-route-attr-data-u8 decoder bv pos)
229
  (make-u8-route-attr (bytevector-u8-ref bv pos)))
230
231
(define (deserialize-route-attr-data-bv decoder bv pos)
232
  (make-bv-route-attr bv))
233
234
(define (deserialize-route-attr-data-ethernet decoder bv pos)
235
  (make-ethernet-route-attr
236
    (string-join (map (lambda (n)
237
                        (let ((s (number->string n 16)))
238
                          (if (equal? (string-length s) 1)
239
                              (string-append "0" s)
240
                              s)))
241
                      (bytevector->u8-list bv))
242
                 ":")))
243
244
(define (deserialize-route-attr-data-ipv4 decoder bv pos)
245
  (make-ipv4-route-attr
246
    (string-join (map (lambda (n) (number->string n))
247
                      (bytevector->u8-list bv))
248
                 ".")))
249
250
(define (deserialize-route-attr-data-ipv6 decoder bv pos)
251
  (define (ipv6->number addr)
252
    (let loop ((addr (bytevector->u8-list addr)) (num 0))
253
      (match addr
254
        (() num)
255
        ((byte addr ...)
256
         (loop addr (+ (* 256 num) byte))))))
257
  (make-ipv6-route-attr
258
    (inet-ntop AF_INET6 (ipv6->number bv))))
259
260
(define (deserialize-route-attr-data-route-cache-info decoder bv pos)
261
  (make-route-cache-info-attr
262
    (bytevector-u32-ref bv pos (native-endianness))
263
    (bytevector-u32-ref bv (+ pos 4) (native-endianness))
264
    (bytevector-u32-ref bv (+ pos 8) (native-endianness))
265
    (bytevector-u32-ref bv (+ pos 12) (native-endianness))))
266
267
(define %default-route-link-attr-decoder
268
  `((,IFLA_ADDRESS . ,deserialize-route-attr-data-ethernet)
269
    (,IFLA_BROADCAST . ,deserialize-route-attr-data-ethernet)
270
    (,IFLA_IFNAME . ,deserialize-route-attr-data-string)
271
    (,IFLA_MTU . ,deserialize-route-attr-data-u32)
272
    (,IFLA_LINK . ,deserialize-route-attr-data-u32)
273
    (,IFLA_QDISC . ,deserialize-route-attr-data-string)
274
    (,IFLA_OPERSTATE . ,deserialize-route-attr-data-u8)
275
    (,IFLA_LINKMODE . ,deserialize-route-attr-data-u8)
276
    (,IFLA_GROUP . ,deserialize-route-attr-data-u32)
277
    (,IFLA_TXQLEN . ,deserialize-route-attr-data-u32)
278
    (,IFLA_LINKINFO . ,(deserialize-route-attr-data-nested 'linkinfo-attr))
279
    ;; TODO: struct rtnl_link_stats
280
    ;(,IFLA_STATS . ,deserialize-route-attr-data-stats)
281
    (default . ,deserialize-route-attr-data-bv)))
282
283
(define %default-route-link-info-attr-decoder
284
  `((,IFLA_INFO_KIND . ,deserialize-route-attr-data-string)
285
    (default . ,deserialize-route-attr-data-bv)))
286
287
(define (default-route-addr-attr-decoder address-decoder)
288
  `((,IFA_ADDRESS . ,address-decoder)
289
    (,IFA_LOCAL . ,address-decoder)
290
    (,IFA_LABEL . ,deserialize-route-attr-data-string)
291
    (,IFA_BROADCAST . ,address-decoder)
292
    (,IFA_ANYCAST . ,address-decoder)
293
    (,IFA_FLAGS . ,deserialize-route-attr-data-u32)
294
    (,IFA_CACHEINFO . ,deserialize-route-attr-data-route-cache-info)
295
    (,IFA_RT_PRIORITY . ,deserialize-route-attr-data-u32)
296
    (default . ,deserialize-route-attr-data-bv)))
297
298
(define (default-route-route-attr-decoder address-decoder)
299
  `((,RTA_DST . ,address-decoder)
300
    (,RTA_SRC . ,address-decoder)
301
    (,RTA_IIF . ,deserialize-route-attr-data-u32)
302
    (,RTA_OIF . ,deserialize-route-attr-data-u32)
303
    (,RTA_GATEWAY . ,address-decoder)
304
    (,RTA_PRIORITY . ,deserialize-route-attr-data-u32)
305
    (,RTA_PREFSRC . ,address-decoder)
306
    (,RTA_METRICS . ,deserialize-route-attr-data-u32)
307
    ;; TODO: struct rtnexthop
308
    ;(,RTA_MULTIPATH . ,deserialize-route-attr-data-rt-next-hop)
309
    (,RTA_FLOW . ,deserialize-route-attr-data-u32)
310
    ; TODO: struct rta_cacheinfo
311
    ;(,RTA_CACHEINFO . ,deserialize-route-attr-data-rta-cache-info)
312
    (,RTA_TABLE . ,deserialize-route-attr-data-u32)
313
    (,RTA_MARK . ,deserialize-route-attr-data-u32)
314
    ;; TODO: struct rta_mfc_stats
315
    ;(,RTA_MFC_STATS . ,deserialize-route-attr-data-rta-mfc-stats)
316
    ;; TODO: struct rtvia
317
    ;(,RTA_VIA . ,,deserialize-route-attr-data-rtvia)
318
    (,RTA_NEWDST . ,address-decoder)
319
    (,RTA_PREF . ,deserialize-route-attr-data-u8)
320
    (,RTA_ENCAP_TYPE . ,deserialize-route-attr-data-u16)
321
    ;; TODO: defined by RTA_ENCAP_TYPE
322
    ;(,RTA_ENCAP . ??)
323
    (,RTA_EXPIRES . ,deserialize-route-attr-data-u32)
324
    (default . ,deserialize-route-attr-data-bv)))
325
326
(define %default-route-addr-ipv4-attr-decoder
327
  (default-route-addr-attr-decoder deserialize-route-attr-data-ipv4))
328
329
(define %default-route-addr-ipv6-attr-decoder
330
  (default-route-addr-attr-decoder deserialize-route-attr-data-ipv6))
331
332
(define %default-route-route-ipv4-attr-decoder
333
  (default-route-route-attr-decoder deserialize-route-attr-data-ipv4))
334
335
(define %default-route-route-ipv6-attr-decoder
336
  (default-route-route-attr-decoder deserialize-route-attr-data-ipv6))
337