Skip to content

Commit afbddc7

Browse files
committed
ovs: add match parser for tun_id
1 parent 42448ff commit afbddc7

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

ovs/matchparser.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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.
271306
func 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+
}

ovs/matchparser_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package ovs
1616

1717
import (
1818
"net"
19+
"reflect"
1920
"strings"
2021
"testing"
2122
)
@@ -254,6 +255,34 @@ func Test_parseMatch(t *testing.T) {
254255
s: "ct_zone=1/1",
255256
invalid: true,
256257
},
258+
{
259+
s: "tun_id=",
260+
invalid: true,
261+
},
262+
{
263+
s: "tun_id=xyzzy",
264+
invalid: true,
265+
},
266+
{
267+
s: "tun_id=0",
268+
final: "tun_id=0x0",
269+
m: TunnelID(0),
270+
},
271+
{
272+
s: "tun_id=1",
273+
final: "tun_id=0x1",
274+
m: TunnelID(1),
275+
},
276+
{
277+
s: "tun_id=0x000000000000000a",
278+
final: "tun_id=0xa",
279+
m: TunnelID(10),
280+
},
281+
{
282+
s: "tun_id=0x000000000000000a/00000000000000002",
283+
final: "tun_id=0xa/0x2",
284+
m: TunnelIDWithMask(10, 2),
285+
},
257286
}
258287

259288
for _, tt := range tests {
@@ -271,6 +300,11 @@ func Test_parseMatch(t *testing.T) {
271300
return
272301
}
273302

303+
if !reflect.DeepEqual(tt.m, m) {
304+
t.Fatalf("unexpected matcher:\n- want: %q\n- got: %q",
305+
tt.m, m)
306+
}
307+
274308
s, err := m.MarshalText()
275309
if err != nil {
276310
t.Fatalf("unexpected error: %v", err)

0 commit comments

Comments
 (0)