@@ -70,9 +70,11 @@ func parseMatch(key string, value string) (Match, error) {
70
70
return parseVLANTCI (value )
71
71
case ctMark :
72
72
return parseCTMark (value )
73
+ case tunID :
74
+ return parseTunID (value )
73
75
}
74
76
75
- return nil , fmt .Errorf ("no action matched for %s=%s" , key , value )
77
+ return nil , fmt .Errorf ("no match parser found for %s=%s" , key , value )
76
78
}
77
79
78
80
// parseClampInt calls strconv.Atoi on s, and then ensures that s is less than
@@ -267,6 +269,39 @@ func parseCTMark(value string) (Match, error) {
267
269
}
268
270
}
269
271
272
+ // parseTunID parses a tunID Match from value.
273
+ func parseTunID (value string ) (Match , error ) {
274
+ var values []uint64
275
+ for _ , s := range strings .Split (value , "/" ) {
276
+ if ! strings .HasPrefix (s , hexPrefix ) {
277
+ v , err := strconv .Atoi (s )
278
+ if err != nil {
279
+ return nil , err
280
+ }
281
+
282
+ values = append (values , uint64 (v ))
283
+ continue
284
+ }
285
+
286
+ v , err := parseHexUint64 (s )
287
+ if err != nil {
288
+ return nil , err
289
+ }
290
+
291
+ values = append (values , v )
292
+ }
293
+
294
+ switch len (values ) {
295
+ case 1 :
296
+ return TunnelID (values [0 ]), nil
297
+ case 2 :
298
+ return TunnelIDWithMask (values [0 ], values [1 ]), nil
299
+ // Match had too many parts, e.g. "tun_id=10/10/10"
300
+ default :
301
+ return nil , fmt .Errorf ("invalid tun_id match: %q" , value )
302
+ }
303
+ }
304
+
270
305
// pareHexUint16 parses a uint16 value from a hexadecimal string.
271
306
func parseHexUint16 (value string ) (uint16 , error ) {
272
307
b , err := hex .DecodeString (strings .TrimPrefix (value , hexPrefix ))
@@ -292,3 +327,16 @@ func parseHexUint32(value string) (uint32, error) {
292
327
293
328
return binary .BigEndian .Uint32 (b ), nil
294
329
}
330
+
331
+ // pareHexUint64 parses a uint64 value from a hexadecimal string.
332
+ func parseHexUint64 (value string ) (uint64 , error ) {
333
+ b , err := hex .DecodeString (strings .TrimPrefix (value , hexPrefix ))
334
+ if err != nil {
335
+ return 0 , err
336
+ }
337
+ if len (b ) != 8 {
338
+ return 0 , errors .New ("hexadecimal value must be eight bytes in length" )
339
+ }
340
+
341
+ return binary .BigEndian .Uint64 (b ), nil
342
+ }
0 commit comments