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