guile-netlink/netlink/route/attrs.scm

attrs.scm

1
;;;; Copyright (C) 2020 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 (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-u8-route-attr
32
           make-u16-route-attr
33
           make-u32-route-attr
34
           make-s32-route-attr
35
           make-nested-route-attr
36
           make-string-route-attr
37
           make-ethernet-route-attr
38
           make-ipv4-route-attr
39
           make-ipv6-route-attr
40
           make-bv-route-attr
41
           deserialize-route-attr
42
           deserialize-route-attr-data-u8
43
           deserialize-route-attr-data-u16
44
           deserialize-route-attr-data-u32
45
           deserialize-route-attr-data-s32
46
           deserialize-route-attr-data-nested
47
           deserialize-route-attr-data-string
48
           deserialize-route-attr-data-ethernet
49
           deserialize-route-attr-data-ipv4
50
           deserialize-route-attr-data-ipv6
51
           deserialize-route-attr-data-bv
52
           %default-route-addr-ipv4-attr-decoder
53
           %default-route-addr-ipv6-attr-decoder
54
           %default-route-link-attr-decoder
55
           %default-route-link-info-attr-decoder
56
           %default-route-route-ipv4-attr-decoder
57
           %default-route-route-ipv6-attr-decoder))
58
59
(define (deserialize-attr-list context decoder bv pos)
60
  (let ((len (bytevector-length bv)))
61
    (let loop ((pos pos) (attrs '()))
62
      (if (>= pos len)
63
          attrs
64
          (let ((attr (deserialize context decoder bv pos)))
65
            (loop (+ pos (align (data-size attr) 4))
66
                  (cons attr attrs)))))))
67
68
(define-data-type route-attr
69
  attr-type-size
70
  (lambda (attr pos bv)
71
    (match attr
72
      (($ route-attr-type type data)
73
       (bytevector-u16-set! bv pos (attr-type-size attr) (native-endianness))
74
       (bytevector-u16-set! bv (+ pos 2) type (native-endianness))
75
       (serialize data (+ pos 4) bv))))
76
  (type route-attr-kind route-attr-type-type)
77
  (data route-attr-data route-attr-type-data))
78
79
(define (attr-type-size attr)
80
  (+ 4 (data-size (route-attr-type-data attr))))
81
82
(define (make-u8-route-attr num)
83
  (make-nl-data
84
    num
85
    (const 1)
86
    (lambda (data pos bv)
87
      (bytevector-u8-set! bv pos data))))
88
89
(define (make-u16-route-attr num)
90
  (make-nl-data
91
    num
92
    (const 2)
93
    (lambda (data pos bv)
94
      (bytevector-u16-set! bv pos data (native-endianness)))))
95
96
(define (make-u32-route-attr num)
97
  (make-nl-data
98
    num
99
    (const 4)
100
    (lambda (data pos bv)
101
      (bytevector-u32-set! bv pos data (native-endianness)))))
102
103
(define (make-s32-route-attr num)
104
  (make-nl-data
105
    num
106
    (const 4)
107
    (lambda (data pos bv)
108
      (bytevector-s32-set! bv pos data (native-endianness)))))
109
110
(define (make-nested-route-attr lst)
111
  (make-nl-data
112
    lst
113
    route-attr-list-size
114
    serialize-route-attr-list))
115
116
(define (make-string-route-attr str)
117
  (make-nl-data
118
    str
119
    (lambda (str) (bytevector-length (string->utf8 str)))
120
    (lambda (data pos bv)
121
      (let ((s (string->utf8 data)))
122
        (bytevector-copy! s 0 bv pos (bytevector-length s))))))
123
124
(define (ethernet->bv addr)
125
  (u8-list->bytevector (map (lambda (n) (string->number n 16))
126
                            (string-split addr #\:))))
127
(define (make-ethernet-route-attr addr)
128
  (make-nl-data
129
    addr
130
    (lambda (addr) (bytevector-length (ethernet->bv addr)))
131
    (lambda (data pos bv)
132
      (let ((a (ethernet->bv data)))
133
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
134
135
(define (ipv4->bv addr)
136
  (u8-list->bytevector (map (lambda (n) (string->number n))
137
                            (string-split addr #\.))))
138
(define (make-ipv4-route-attr addr)
139
  (make-nl-data
140
    addr
141
    (lambda (addr) (bytevector-length (ipv4->bv addr)))
142
    (lambda (data pos bv)
143
      (let ((a (ipv4->bv data)))
144
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
145
146
;16 bytes
147
(define (ipv6->bv addr)
148
  (let loop ((num (inet-pton AF_INET6 addr)) (lst '()))
149
    (match lst
150
      ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)
151
       (u8-list->bytevector (reverse lst)))
152
      (_
153
       (loop (quotient num 256) (cons (modulo num 256) lst))))))
154
(define (make-ipv6-route-attr addr)
155
  (make-nl-data
156
    addr
157
    (lambda (addr) (bytevector-length (ipv6->bv addr)))
158
    (lambda (data pos bv)
159
      (let ((a (ipv6->bv data)))
160
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
161
162
(define (make-bv-route-attr bv)
163
  (make-nl-data
164
    bv
165
    (lambda (bv) (bytevector-length bv))
166
    (lambda (data pos bv)
167
      (bytevector-copy! data 0 bv pos (bytevector-length data)))))
168
169
(define (deserialize-route-attr message-type)
170
  (lambda (decoder bv pos)
171
    (let* ((len (bytevector-u16-ref bv pos (native-endianness)))
172
           (type (bytevector-u16-ref bv (+ pos 2) (native-endianness)))
173
           (deserialize (get-next-deserialize decoder message-type type)))
174
      (if (= len 0)
175
          (let ((data-bv (make-bytevector 0)))
176
            (make-route-attr type (deserialize decoder data-bv 0)))
177
          (let ((data-bv (make-bytevector (- len 4))))
178
            (bytevector-copy! bv (+ pos 4) data-bv 0 (- len 4))
179
            (make-route-attr
180
              type
181
              (deserialize decoder data-bv 0)))))))
182
183
(define (deserialize-route-attr-data-nested attr-type)
184
  (lambda (decoder bv pos)
185
    (make-nested-route-attr
186
      (deserialize-attr-list attr-type decoder bv pos))))
187
188
(define (deserialize-route-attr-data-string decoder bv pos)
189
  (make-string-route-attr
190
    (or (false-if-exception (string-trim-right (utf8->string bv) #\nul))
191
        (make-string (bytevector-length bv) #\a))))
192
193
(define (deserialize-route-attr-data-u32 decoder bv pos)
194
  (make-u32-route-attr (bytevector-u32-ref bv pos (native-endianness))))
195
196
(define (deserialize-route-attr-data-s32 decoder bv pos)
197
  (make-s32-route-attr (bytevector-s32-ref bv pos (native-endianness))))
198
199
(define (deserialize-route-attr-data-u16 decoder bv pos)
200
  (make-u32-route-attr (bytevector-u16-ref bv pos (native-endianness))))
201
202
(define (deserialize-route-attr-data-u8 decoder bv pos)
203
  (make-u8-route-attr (bytevector-u8-ref bv pos)))
204
205
(define (deserialize-route-attr-data-bv decoder bv pos)
206
  (make-bv-route-attr bv))
207
208
(define (deserialize-route-attr-data-ethernet decoder bv pos)
209
  (make-ethernet-route-attr
210
    (string-join (map (lambda (n)
211
                        (let ((s (number->string n 16)))
212
                          (if (equal? (string-length s) 1)
213
                              (string-append "0" s)
214
                              s)))
215
                      (bytevector->u8-list bv))
216
                 ":")))
217
218
(define (deserialize-route-attr-data-ipv4 decoder bv pos)
219
  (make-ipv4-route-attr
220
    (string-join (map (lambda (n) (number->string n))
221
                      (bytevector->u8-list bv))
222
                 ".")))
223
224
(define (deserialize-route-attr-data-ipv6 decoder bv pos)
225
  (define (ipv6->number addr)
226
    (let loop ((addr (bytevector->u8-list addr)) (num 0))
227
      (match addr
228
        (() num)
229
        ((byte addr ...)
230
         (loop addr (+ (* 256 num) byte))))))
231
  (make-ipv6-route-attr
232
    (inet-ntop AF_INET6 (ipv6->number bv))))
233
234
(define %default-route-link-attr-decoder
235
  `((,IFLA_ADDRESS . ,deserialize-route-attr-data-ethernet)
236
    (,IFLA_BROADCAST . ,deserialize-route-attr-data-ethernet)
237
    (,IFLA_IFNAME . ,deserialize-route-attr-data-string)
238
    (,IFLA_MTU . ,deserialize-route-attr-data-u32)
239
    (,IFLA_LINK . ,deserialize-route-attr-data-u32)
240
    (,IFLA_QDISC . ,deserialize-route-attr-data-string)
241
    (,IFLA_OPERSTATE . ,deserialize-route-attr-data-u8)
242
    (,IFLA_LINKMODE . ,deserialize-route-attr-data-u8)
243
    (,IFLA_GROUP . ,deserialize-route-attr-data-u32)
244
    (,IFLA_TXQLEN . ,deserialize-route-attr-data-u32)
245
    (,IFLA_LINKINFO . ,(deserialize-route-attr-data-nested 'linkinfo-attr))
246
    ;; TODO: struct rtnl_link_stats
247
    ;(,IFLA_STATS . ,deserialize-route-attr-data-stats)
248
    (default . ,deserialize-route-attr-data-bv)))
249
250
(define %default-route-link-info-attr-decoder
251
  `((,IFLA_INFO_KIND . ,deserialize-route-attr-data-string)
252
    (default . ,deserialize-route-attr-data-bv)))
253
254
(define (default-route-addr-attr-decoder address-decoder)
255
  `((,IFA_ADDRESS . ,address-decoder)
256
    (,IFA_LOCAL . ,address-decoder)
257
    (,IFA_LABEL . ,deserialize-route-attr-data-string)
258
    (,IFA_BROADCAST . ,address-decoder)
259
    (,IFA_ANYCAST . ,address-decoder)
260
    (,IFA_FLAGS . ,deserialize-route-attr-data-u32)
261
    ;; TODO: struct ifa_cacheinfo
262
    ;(,IFA_CACHEINFO . ,deserialize-route-attr-data-cache-info)
263
    (default . ,deserialize-route-attr-data-bv)))
264
265
(define (default-route-route-attr-decoder address-decoder)
266
  `((,RTA_DST . ,address-decoder)
267
    (,RTA_SRC . ,address-decoder)
268
    (,RTA_IIF . ,deserialize-route-attr-data-u32)
269
    (,RTA_OIF . ,deserialize-route-attr-data-u32)
270
    (,RTA_GATEWAY . ,address-decoder)
271
    (,RTA_PRIORITY . ,deserialize-route-attr-data-u32)
272
    (,RTA_PREFSRC . ,address-decoder)
273
    (,RTA_METRICS . ,deserialize-route-attr-data-u32)
274
    ;; TODO: struct rtnexthop
275
    ;(,RTA_MULTIPATH . ,deserialize-route-attr-data-rt-next-hop)
276
    (,RTA_FLOW . ,deserialize-route-attr-data-u32)
277
    ; TODO: struct rta_cacheinfo
278
    ;(,RTA_CACHEINFO . ,deserialize-route-attr-data-rta-cache-info)
279
    (,RTA_TABLE . ,deserialize-route-attr-data-u32)
280
    (,RTA_MARK . ,deserialize-route-attr-data-u32)
281
    ;; TODO: struct rta_mfc_stats
282
    ;(,RTA_MFC_STATS . ,deserialize-route-attr-data-rta-mfc-stats)
283
    ;; TODO: struct rtvia
284
    ;(,RTA_VIA . ,,deserialize-route-attr-data-rtvia)
285
    (,RTA_NEWDST . ,address-decoder)
286
    (,RTA_PREF . ,deserialize-route-attr-data-u8)
287
    (,RTA_ENCAP_TYPE . ,deserialize-route-attr-data-u16)
288
    ;; TODO: defined by RTA_ENCAP_TYPE
289
    ;(,RTA_ENCAP . ??)
290
    (,RTA_EXPIRES . ,deserialize-route-attr-data-u32)
291
    (default . ,deserialize-route-attr-data-bv)))
292
293
(define %default-route-addr-ipv4-attr-decoder
294
  (default-route-addr-attr-decoder deserialize-route-attr-data-ipv4))
295
296
(define %default-route-addr-ipv6-attr-decoder
297
  (default-route-addr-attr-decoder deserialize-route-attr-data-ipv6))
298
299
(define %default-route-route-ipv4-attr-decoder
300
  (default-route-route-attr-decoder deserialize-route-attr-data-ipv4))
301
302
(define %default-route-route-ipv6-attr-decoder
303
  (default-route-route-attr-decoder deserialize-route-attr-data-ipv6))
304