@@ -70,9 +70,11 @@ func parseMatch(key string, value string) (Match, error) {
7070 return parseVLANTCI (value )
7171 case ctMark :
7272 return parseCTMark (value )
73+ case tunID :
74+ return parseTunID (value )
7375 }
7476
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 )
7678}
7779
7880// parseClampInt calls strconv.Atoi on s, and then ensures that s is less than
@@ -267,6 +269,39 @@ func parseCTMark(value string) (Match, error) {
267269 }
268270}
269271
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+
270305// pareHexUint16 parses a uint16 value from a hexadecimal string.
271306func parseHexUint16 (value string ) (uint16 , error ) {
272307 b , err := hex .DecodeString (strings .TrimPrefix (value , hexPrefix ))
@@ -292,3 +327,16 @@ func parseHexUint32(value string) (uint32, error) {
292327
293328 return binary .BigEndian .Uint32 (b ), nil
294329}
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