func()

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
}