Skip to content

Commit b433cb8

Browse files
authored
Merge pull request #86 from digitalocean/bsomogyi/metadata-matchparser
Extend Metadata Matchparser with Mask
2 parents 6de2edd + 7e0ccd2 commit b433cb8

File tree

2 files changed

+77
-24
lines changed

2 files changed

+77
-24
lines changed

ovs/match.go

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,48 @@ func UnsetState(state CTState) string {
12401240
return fmt.Sprintf("-%s", state)
12411241
}
12421242

1243+
// Metadata returns a Match that matches the given Metadata exactly.
1244+
func Metadata(id uint64) Match {
1245+
return &metadataMatch{
1246+
data: id,
1247+
mask: 0,
1248+
}
1249+
}
1250+
1251+
// MetadataWithMask returns a Match with specified Metadata and mask.
1252+
func MetadataWithMask(id, mask uint64) Match {
1253+
return &metadataMatch{
1254+
data: id,
1255+
mask: mask,
1256+
}
1257+
}
1258+
1259+
var _ Match = &metadataMatch{}
1260+
1261+
// A metadataMatch is a Match against a Metadata field.
1262+
type metadataMatch struct {
1263+
data uint64
1264+
mask uint64
1265+
}
1266+
1267+
// GoString implements Match.
1268+
func (m *metadataMatch) GoString() string {
1269+
if m.mask > 0 {
1270+
return fmt.Sprintf("ovs.MetadataWithMask(%#x, %#x)", m.data, m.mask)
1271+
}
1272+
1273+
return fmt.Sprintf("ovs.Metadata(%#x)", m.data)
1274+
}
1275+
1276+
// MarshalText implements Match.
1277+
func (m *metadataMatch) MarshalText() ([]byte, error) {
1278+
if m.mask == 0 {
1279+
return bprintf("%s=%#x", metadata, m.data), nil
1280+
}
1281+
1282+
return bprintf("%s=%#x/%#x", metadata, m.data, m.mask), nil
1283+
}
1284+
12431285
// TCPFlags matches packets using their enabled TCP flags, when matching TCP
12441286
// flags on a TCP segment. Use the SetTCPFlag and UnsetTCPFlag functions to
12451287
// populate the parameter list for this function.
@@ -1381,30 +1423,6 @@ func (m *tunnelMatch) MarshalText() ([]byte, error) {
13811423
return matchIPv4AddressOrCIDR(fmt.Sprintf("tun_%s", m.srcdst), m.ip)
13821424
}
13831425

1384-
// Metadata returns a Match that matches the given metadata value.
1385-
func Metadata(m uint64) Match {
1386-
return &metadataMatch{
1387-
m: m,
1388-
}
1389-
}
1390-
1391-
var _ Match = &metadataMatch{}
1392-
1393-
// A metadataMatch is a Match against a metadata value.
1394-
type metadataMatch struct {
1395-
m uint64
1396-
}
1397-
1398-
// GoString implements Match.
1399-
func (m *metadataMatch) GoString() string {
1400-
return fmt.Sprintf("ovs.Metadata(%#x)", m.m)
1401-
}
1402-
1403-
// MarshalText implements Match.
1404-
func (m *metadataMatch) MarshalText() ([]byte, error) {
1405-
return bprintf("%s=%#x", metadata, m.m), nil
1406-
}
1407-
14081426
// matchIPv4AddressOrCIDR attempts to create a Match using the specified key
14091427
// and input string, which could be interpreted as an IPv4 address or IPv4
14101428
// CIDR block.

ovs/matchparser.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ func parseMatch(key string, value string) (Match, error) {
8686
return IPv6Source(value), nil
8787
case ipv6DST:
8888
return IPv6Destination(value), nil
89+
case metadata:
90+
return parseMetadata(value)
8991
case tunv6SRC:
9092
return IPv6Source(value), nil
9193
case tunv6DST:
@@ -479,6 +481,39 @@ func parseCTMark(value string) (Match, error) {
479481
}
480482
}
481483

484+
// parseMetadata parses a Metadata Match from value.
485+
func parseMetadata(value string) (Match, error) {
486+
var values []uint64
487+
for _, s := range strings.Split(value, "/") {
488+
if !strings.HasPrefix(s, hexPrefix) {
489+
v, err := strconv.Atoi(s)
490+
if err != nil {
491+
return nil, err
492+
}
493+
494+
values = append(values, uint64(v))
495+
continue
496+
}
497+
498+
v, err := parseHexUint64(s)
499+
if err != nil {
500+
return nil, err
501+
}
502+
503+
values = append(values, v)
504+
}
505+
506+
switch len(values) {
507+
case 1:
508+
return Metadata(values[0]), nil
509+
case 2:
510+
return MetadataWithMask(values[0], values[1]), nil
511+
// Match had too many parts, e.g. "metadata=10/10/10"
512+
default:
513+
return nil, fmt.Errorf("invalid metadata match: %q", value)
514+
}
515+
}
516+
482517
// parseTunID parses a tunID Match from value.
483518
func parseTunID(value string) (Match, error) {
484519
var values []uint64

0 commit comments

Comments
 (0)