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