in pkg/skoop/netstack/iptables.go [210:276]
func (set *Set) Match(ctx context.Context, packet *model.Packet, _, _ string) (bool, error) {
setName, flags, err := set.parseSetArgument()
if err != nil {
return false, err
}
ipsetManager, ok := ctx.Value(ContextIPSetKey).(*IPSetManager)
if !ok || ipsetManager == nil {
return false, fmt.Errorf("cannot get ipset from context")
}
ipset := ipsetManager.GetIPSet(setName)
if ipset == nil {
return false, nil
}
ip := func(field string) net.IP {
switch field {
case "src":
return packet.Src
case "dst":
return packet.Dst
default:
return net.IPv4(0, 0, 0, 0)
}
}
port := func(field string) uint16 {
switch field {
case "src":
return packet.Sport
case "dst":
return packet.Dport
default:
return 0
}
}
var key string
switch ipset.Type {
case "hash:net":
addr := ip(flags)
for m := range ipset.Members {
if match, _ := utils.IPMatchPrefix(addr, m); match {
return true, nil
}
}
return false, nil
case "hash:ip,port":
fields := strings.Split(flags, ",")
addr := ip(fields[0])
port := port(fields[1])
key = fmt.Sprintf("%s,%s:%d", addr, packet.Protocol, port)
case "hash:ip,port,ip":
fields := strings.Split(flags, ",")
addr := ip(fields[0])
port := port(fields[1])
addr2 := ip(fields[2])
key = fmt.Sprintf("%s,%s:%d,%s", addr, packet.Protocol, port, addr2)
case "bitmap:port":
port := port(flags)
key = fmt.Sprintf("%d", port)
default:
return false, ErrIptablesUnsupported{fmt.Sprintf("ipset type %s of %s", ipset.Type, setName)}
}
_, ok = ipset.Members[key]
return ok, nil
}