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-u32
42
           deserialize-route-attr-data-s32
43
           deserialize-route-attr-data-ethernet
44
           deserialize-route-attr-data-ipv4
45
           deserialize-route-attr-data-ipv6
46
           deserialize-route-attr-data-bv
47
           default-route-attr-decoder
48
           %default-route-link-attr-decoder
49
           %default-route-ipv4-attr-decoder
50
           %default-route-ipv6-attr-decoder))
51
52
(define-data-type route-attr
53
  attr-type-size
54
  (lambda (attr pos bv)
55
    (match attr
56
      (($ route-attr-type type data)
57
       (bytevector-u16-set! bv pos (attr-type-size attr) (native-endianness))
58
       (bytevector-u16-set! bv (+ pos 2) type (native-endianness))
59
       (serialize data (+ pos 4) bv))))
60
  (type route-attr-kind route-attr-type-type)
61
  (data route-attr-data route-attr-type-data))
62
63
(define (attr-type-size attr)
64
  (+ 4 (data-size (route-attr-type-data attr))))
65
66
(define (make-u8-route-attr num)
67
  (make-nl-data
68
    num
69
    (const 1)
70
    (lambda (data pos bv)
71
      (bytevector-u8-set! bv pos data))))
72
73
(define (make-u16-route-attr num)
74
  (make-nl-data
75
    num
76
    (const 2)
77
    (lambda (data pos bv)
78
      (bytevector-u16-set! bv pos data (native-endianness)))))
79
80
(define (make-u32-route-attr num)
81
  (make-nl-data
82
    num
83
    (const 4)
84
    (lambda (data pos bv)
85
      (bytevector-u32-set! bv pos data (native-endianness)))))
86
87
(define (make-s32-route-attr num)
88
  (make-nl-data
89
    num
90
    (const 4)
91
    (lambda (data pos bv)
92
      (bytevector-s32-set! bv pos data (native-endianness)))))
93
94
(define (make-string-route-attr str)
95
  (make-nl-data
96
    str
97
    (lambda (str) (bytevector-length (string->utf8 str)))
98
    (lambda (data pos bv)
99
      (let ((s (string->utf8 data)))
100
        (bytevector-copy! s 0 bv pos (bytevector-length s))))))
101
102
(define (ethernet->bv addr)
103
  (u8-list->bytevector (map (lambda (n) (string->number n 16))
104
                            (string-split addr #\:))))
105
(define (make-ethernet-route-attr addr)
106
  (make-nl-data
107
    addr
108
    (lambda (addr) (bytevector-length (ethernet->bv addr)))
109
    (lambda (data pos bv)
110
      (let ((a (ethernet->bv data)))
111
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
112
113
(define (ipv4->bv addr)
114
  (u8-list->bytevector (map (lambda (n) (string->number n))
115
                            (string-split addr #\.))))
116
(define (make-ipv4-route-attr addr)
117
  (make-nl-data
118
    addr
119
    (lambda (addr) (bytevector-length (ipv4->bv addr)))
120
    (lambda (data pos bv)
121
      (let ((a (ipv4->bv data)))
122
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
123
124
;16 bytes
125
(define (ipv6->bv addr)
126
  (let loop ((num (inet-pton AF_INET6 addr)) (lst '()))
127
    (match lst
128
      ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)
129
       (u8-list->bytevector (reverse lst)))
130
      (_
131
       (loop (quotient num 256) (cons (modulo num 256) lst))))))
132
(define (make-ipv6-route-attr addr)
133
  (make-nl-data
134
    addr
135
    (lambda (addr) (bytevector-length (ipv6->bv addr)))
136
    (lambda (data pos bv)
137
      (let ((a (ipv6->bv data)))
138
        (bytevector-copy! a 0 bv pos (bytevector-length a))))))
139
140
(define (make-bv-route-attr bv)
141
  (make-nl-data
142
    bv
143
    (lambda (bv) (bytevector-length bv))
144
    (lambda (data pos bv)
145
      (bytevector-copy! data 0 bv pos (bytevector-length data)))))
146
147
(define (deserialize-route-attr message-type)
148
  (lambda (decoder bv pos)
149
    (let* ((len (bytevector-u16-ref bv pos (native-endianness)))
150
           (type (bytevector-u16-ref bv (+ pos 2) (native-endianness)))
151
           (deserialize (get-next-deserialize decoder message-type type))
152
           (data-bv (make-bytevector (- len 4))))
153
      (bytevector-copy! bv (+ pos 4) data-bv 0 (- len 4))
154
      (make-route-attr
155
        type
156
        (deserialize decoder data-bv 0)))))
157
158
(define (deserialize-route-attr-data-string decoder bv pos)
159
  (make-string-route-attr
160
    (or (false-if-exception (utf8->string bv))
161
        (make-string (bytevector-length bv) #\a))))
162
163
(define (deserialize-route-attr-data-u32 decoder bv pos)
164
  (make-u32-route-attr (bytevector-u32-ref bv pos (native-endianness))))
165
166
(define (deserialize-route-attr-data-s32 decoder bv pos)
167
  (make-s32-route-attr (bytevector-s32-ref bv pos (native-endianness))))
168
169
(define (deserialize-route-attr-data-u8 decoder bv pos)
170
  (make-u8-route-attr (bytevector-u8-ref bv pos)))
171
172
(define (deserialize-route-attr-data-bv decoder bv pos)
173
  (make-bv-route-attr bv))
174
175
(define (deserialize-route-attr-data-ethernet decoder bv pos)
176
  (make-ethernet-route-attr
177
    (string-join (map (lambda (n) (number->string n 16))
178
                      (bytevector->u8-list bv))
179
                 ":")))
180
181
(define (deserialize-route-attr-data-ipv4 decoder bv pos)
182
  (make-ipv4-route-attr
183
    (string-join (map (lambda (n) (number->string n))
184
                      (bytevector->u8-list bv))
185
                 ".")))
186
187
(define (deserialize-route-attr-data-ipv6 decoder bv pos)
188
  (define (ipv6->number addr)
189
    (let loop ((addr (bytevector->u8-list addr)) (num 0))
190
      (match addr
191
        (() num)
192
        ((byte addr ...)
193
         (loop addr (+ (* 256 num) byte))))))
194
  (make-ipv6-route-attr
195
    (inet-ntop AF_INET6 (ipv6->number bv))))
196
197
(define (default-route-attr-decoder deserialize-addr)
198
  `((,IFLA_IFNAME . ,deserialize-route-attr-data-string)
199
    (,IFLA_QDISC . ,deserialize-route-attr-data-string)
200
    (,IFLA_IFALIAS . ,deserialize-route-attr-data-string)
201
    (,IFLA_PHYS_PORT_NAME . ,deserialize-route-attr-data-string)
202
    (,IFLA_MTU . ,deserialize-route-attr-data-u32)
203
    (,IFLA_TXQLEN . ,deserialize-route-attr-data-u32)
204
    (,IFLA_LINK . ,deserialize-route-attr-data-u32)
205
    (,IFLA_WEIGHT . ,deserialize-route-attr-data-u32)
206
    (,IFLA_MASTER . ,deserialize-route-attr-data-u32)
207
    (,IFLA_NUM_VF . ,deserialize-route-attr-data-u32)
208
    (,IFLA_PROMISCUITY . ,deserialize-route-attr-data-u32)
209
    (,IFLA_NUM_TX_QUEUES . ,deserialize-route-attr-data-u32)
210
    (,IFLA_NUM_RX_QUEUES . ,deserialize-route-attr-data-u32)
211
    (,IFLA_GSO_MAX_SEGS . ,deserialize-route-attr-data-u32)
212
    (,IFLA_GSO_MAX_SIZE . ,deserialize-route-attr-data-u32)
213
    (,IFLA_GROUP . ,deserialize-route-attr-data-u32)
214
    (,IFLA_CARRIER_CHANGES . ,deserialize-route-attr-data-u32)
215
    (,IFLA_NET_NS_PID . ,deserialize-route-attr-data-u32)
216
    (,IFLA_NET_NS_FD . ,deserialize-route-attr-data-u32)
217
    (,IFLA_NEW_IFINDEX . ,deserialize-route-attr-data-u32)
218
    (,IFLA_MIN_MTU . ,deserialize-route-attr-data-u32)
219
    (,IFLA_MAX_MTU . ,deserialize-route-attr-data-u32)
220
    (,IFLA_CARRIER_UP_COUNT . ,deserialize-route-attr-data-u32)
221
    (,IFLA_CARRIER_DOWN_COUNT . ,deserialize-route-attr-data-u32)
222
    (,IFLA_OPERSTATE . ,deserialize-route-attr-data-u8)
223
    (,IFLA_LINKMODE . ,deserialize-route-attr-data-u8)
224
    (,IFLA_CARRIER . ,deserialize-route-attr-data-u8)
225
    (,IFLA_PROTO_DOWN . ,deserialize-route-attr-data-u8)
226
    (,IFLA_ADDRESS . ,deserialize-addr)
227
    (,IFLA_BROADCAST . ,deserialize-addr)
228
    (,IFLA_PERM_ADDRESS . ,deserialize-addr)
229
    (default . ,deserialize-route-attr-data-bv)))
230
231
(define %default-route-link-attr-decoder
232
  (default-route-attr-decoder deserialize-route-attr-data-ethernet))
233
234
(define %default-route-ipv4-attr-decoder
235
  (default-route-attr-decoder deserialize-route-attr-data-ipv4))
236
237
(define %default-route-ipv6-attr-decoder
238
  (default-route-attr-decoder deserialize-route-attr-data-ipv6))
239