// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//go:build !build_with_native_toolchain
// +build !build_with_native_toolchain

// Package filter provides the implementation of packet filter.
package filter

import (
	"fmt"
	"sync"

	"go.fuchsia.dev/fuchsia/src/connectivity/network/netstack/fidlconv"
	syslog "go.fuchsia.dev/fuchsia/src/lib/syslog/go"

	"fidl/fuchsia/net/filter"

	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
)

const tag = "filter"

type Filter struct {
	stack          *stack.Stack
	defaultV4Table stack.Table
	defaultV6Table stack.Table

	filterDisabledNICMatcher filterDisabledNICMatcher

	mu struct {
		sync.RWMutex
		rules      []filter.Rule
		v4Table    stack.Table
		v6Table    stack.Table
		generation uint32
	}
}

func New(s *stack.Stack) *Filter {
	defaultTables := stack.DefaultTables(s.Seed(), s.Clock())
	defaultV4Table := defaultTables.GetTable(stack.FilterID, false /* ipv6 */)
	defaultV6Table := defaultTables.GetTable(stack.FilterID, true /* ipv6 */)

	f := &Filter{
		stack:          s,
		defaultV4Table: defaultV4Table,
		defaultV6Table: defaultV6Table,
	}
	f.filterDisabledNICMatcher.init()
	f.mu.Lock()
	f.mu.v4Table = defaultV4Table
	f.mu.v6Table = defaultV6Table
	f.mu.Unlock()
	return f
}

func (f *Filter) enableInterface(id tcpip.NICID) filter.FilterEnableInterfaceResult {
	name := f.stack.FindNICNameFromID(id)
	if name == "" {
		return filter.FilterEnableInterfaceResultWithErr(filter.FilterEnableInterfaceErrorNotFound)
	}
	f.filterDisabledNICMatcher.mu.Lock()
	defer f.filterDisabledNICMatcher.mu.Unlock()
	f.filterDisabledNICMatcher.mu.nicNames[name] = id
	return filter.FilterEnableInterfaceResultWithResponse(filter.FilterEnableInterfaceResponse{})
}

func (f *Filter) disableInterface(id tcpip.NICID) filter.FilterDisableInterfaceResult {
	name := f.stack.FindNICNameFromID(id)
	if name == "" {
		return filter.FilterDisableInterfaceResultWithErr(filter.FilterDisableInterfaceErrorNotFound)
	}
	f.filterDisabledNICMatcher.mu.Lock()
	defer f.filterDisabledNICMatcher.mu.Unlock()
	delete(f.filterDisabledNICMatcher.mu.nicNames, name)
	return filter.FilterDisableInterfaceResultWithResponse(filter.FilterDisableInterfaceResponse{})
}

func (f *Filter) RemovedNIC(id tcpip.NICID) {
	f.filterDisabledNICMatcher.mu.Lock()
	defer f.filterDisabledNICMatcher.mu.Unlock()
	for k, v := range f.filterDisabledNICMatcher.mu.nicNames {
		if v == id {
			delete(f.filterDisabledNICMatcher.mu.nicNames, k)
			break
		}
	}
}

func (f *Filter) getRules() filter.FilterGetRulesResult {
	f.mu.RLock()
	defer f.mu.RUnlock()
	return filter.FilterGetRulesResultWithResponse(filter.FilterGetRulesResponse{
		Rules:      f.mu.rules,
		Generation: f.mu.generation,
	})
}

func (f *Filter) updateRules(rules []filter.Rule, generation uint32) filter.FilterUpdateRulesResult {
	f.mu.RLock()
	g := f.mu.generation
	f.mu.RUnlock()

	if generation != g {
		return filter.FilterUpdateRulesResultWithErr(filter.FilterUpdateRulesErrorGenerationMismatch)
	}

	v4Table, v6Table, ok := f.parseRules(rules)
	if !ok {
		return filter.FilterUpdateRulesResultWithErr(filter.FilterUpdateRulesErrorBadRule)
	}

	f.mu.Lock()
	defer f.mu.Unlock()
	if f.mu.generation != generation {
		return filter.FilterUpdateRulesResultWithErr(filter.FilterUpdateRulesErrorGenerationMismatch)
	}

	f.mu.rules = rules
	f.mu.v4Table = v4Table
	f.mu.v6Table = v6Table

	iptables := f.stack.IPTables()
	if err := iptables.ReplaceTable(stack.FilterID, v4Table, false /* ipv6 */); err != nil {
		_ = syslog.ErrorTf(tag, "error replacing iptables = %s", err)
		return filter.FilterUpdateRulesResultWithErr(filter.FilterUpdateRulesErrorInternal)
	}
	if err := iptables.ReplaceTable(stack.FilterID, v6Table, true /* ipv6 */); err != nil {
		_ = syslog.ErrorTf(tag, "error replacing ip6tables = %s", err)
		return filter.FilterUpdateRulesResultWithErr(filter.FilterUpdateRulesErrorInternal)
	}
	f.mu.generation++
	return filter.FilterUpdateRulesResultWithResponse(filter.FilterUpdateRulesResponse{})
}

func isPortRangeAny(p filter.PortRange) bool {
	return p.Start == 0 && p.End == 0
}

func isPortRangeValid(p filter.PortRange) bool {
	return isPortRangeAny(p) || (1 <= p.Start && p.Start <= p.End)
}

func (f *Filter) parseRules(rules []filter.Rule) (v4Table stack.Table, v6Table stack.Table, ok bool) {
	type ipType int
	const (
		generic ipType = iota
		ipv4Only
		ipv6Only
	)

	if len(rules) == 0 {
		return f.defaultV4Table, f.defaultV6Table, true
	}

	allowPacketsForFilterDisbledNICs := stack.Rule{
		Matchers: []stack.Matcher{&f.filterDisabledNICMatcher},
		Target:   &stack.AcceptTarget{},
	}
	v4InputRules := []stack.Rule{allowPacketsForFilterDisbledNICs}
	v4OutputRules := []stack.Rule{allowPacketsForFilterDisbledNICs}
	v6InputRules := []stack.Rule{allowPacketsForFilterDisbledNICs}
	v6OutputRules := []stack.Rule{allowPacketsForFilterDisbledNICs}

	for _, r := range rules {
		var ipTypeValue ipType
		var ipHdrFilter stack.IPHeaderFilter

		if src := r.SrcSubnet; src != nil {
			ipHdrFilter.SrcInvert = r.SrcSubnetInvertMatch
			subnet := fidlconv.ToTCPIPSubnet(*src)
			ipHdrFilter.Src = subnet.ID()
			ipHdrFilter.SrcMask = tcpip.Address(subnet.Mask())

			switch l := len(ipHdrFilter.Src); l {
			case header.IPv4AddressSize:
				ipTypeValue = ipv4Only
			case header.IPv6AddressSize:
				ipTypeValue = ipv6Only
			default:
				return stack.Table{}, stack.Table{}, false
			}
		}

		if dst := r.DstSubnet; dst != nil {
			ipHdrFilter.DstInvert = r.DstSubnetInvertMatch
			subnet := fidlconv.ToTCPIPSubnet(*dst)
			ipHdrFilter.Dst = subnet.ID()
			ipHdrFilter.DstMask = tcpip.Address(subnet.Mask())

			var dstIpType ipType
			switch l := len(ipHdrFilter.Dst); l {
			case header.IPv4AddressSize:
				dstIpType = ipv4Only
			case header.IPv6AddressSize:
				dstIpType = ipv6Only
			default:
				return stack.Table{}, stack.Table{}, false
			}

			if ipTypeValue == generic {
				ipTypeValue = dstIpType
			} else if ipTypeValue != dstIpType {
				return stack.Table{}, stack.Table{}, false
			}
		}

		var matchers []stack.Matcher
		switch r.Proto {
		case filter.SocketProtocolAny:
		case filter.SocketProtocolIcmp:
			if ipTypeValue == ipv6Only {
				return stack.Table{}, stack.Table{}, false
			}
			ipTypeValue = ipv4Only

			ipHdrFilter.CheckProtocol = true
			ipHdrFilter.Protocol = header.ICMPv4ProtocolNumber
		case filter.SocketProtocolTcp:
			ipHdrFilter.CheckProtocol = true
			ipHdrFilter.Protocol = header.TCPProtocolNumber

			if !isPortRangeAny(r.SrcPortRange) {
				if !isPortRangeValid(r.SrcPortRange) {
					return stack.Table{}, stack.Table{}, false
				}
				matchers = append(matchers, NewTCPSourcePortMatcher(r.SrcPortRange.Start, r.SrcPortRange.End))
			}

			if !isPortRangeAny(r.DstPortRange) {
				if !isPortRangeValid(r.DstPortRange) {
					return stack.Table{}, stack.Table{}, false
				}
				matchers = append(matchers, NewTCPDestinationPortMatcher(r.DstPortRange.Start, r.DstPortRange.End))
			}

		case filter.SocketProtocolUdp:
			ipHdrFilter.CheckProtocol = true
			ipHdrFilter.Protocol = header.UDPProtocolNumber

			if !isPortRangeAny(r.SrcPortRange) {
				if !isPortRangeValid(r.SrcPortRange) {
					return stack.Table{}, stack.Table{}, false
				}
				matchers = append(matchers, NewUDPSourcePortMatcher(r.SrcPortRange.Start, r.SrcPortRange.End))
			}

			if !isPortRangeAny(r.DstPortRange) {
				if !isPortRangeValid(r.DstPortRange) {
					return stack.Table{}, stack.Table{}, false
				}
				matchers = append(matchers, NewUDPDestinationPortMatcher(r.DstPortRange.Start, r.DstPortRange.End))
			}
		case filter.SocketProtocolIcmpv6:
			if ipTypeValue == ipv4Only {
				return stack.Table{}, stack.Table{}, false
			}
			ipTypeValue = ipv6Only

			ipHdrFilter.CheckProtocol = true
			ipHdrFilter.Protocol = header.ICMPv6ProtocolNumber
		default:
			return stack.Table{}, stack.Table{}, false
		}

		var target stack.Target
		switch r.Action {
		case filter.ActionPass:
			target = &stack.AcceptTarget{}
			if r.KeepState {
				// TODO(https://fxbug.dev/68501): Support keep state.
				return stack.Table{}, stack.Table{}, false
			}
		case filter.ActionDrop:
			target = &stack.DropTarget{}
		default:
			return stack.Table{}, stack.Table{}, false
		}

		rule := stack.Rule{
			Filter:   ipHdrFilter,
			Matchers: matchers,
			Target:   target,
		}

		switch r.Direction {
		case filter.DirectionIncoming:
			switch ipTypeValue {
			case generic:
				v4InputRules = append(v4InputRules, rule)
				v6InputRules = append(v6InputRules, rule)
			case ipv4Only:
				v4InputRules = append(v4InputRules, rule)
			case ipv6Only:
				v6InputRules = append(v6InputRules, rule)
			default:
				panic(fmt.Sprintf("unrecognied ipTypeValue = %d", ipTypeValue))
			}
		case filter.DirectionOutgoing:
			switch ipTypeValue {
			case generic:
				v4OutputRules = append(v4OutputRules, rule)
				v6OutputRules = append(v6OutputRules, rule)
			case ipv4Only:
				v4OutputRules = append(v4OutputRules, rule)
			case ipv6Only:
				v6OutputRules = append(v6OutputRules, rule)
			default:
				panic(fmt.Sprintf("unrecognied ipTypeValue = %d", ipTypeValue))
			}
		default:
			return stack.Table{}, stack.Table{}, false
		}
	}

	v4InputRules = append(v4InputRules, stack.Rule{Target: &stack.AcceptTarget{}})
	v4OutputRules = append(v4OutputRules, stack.Rule{Target: &stack.AcceptTarget{}})
	v6InputRules = append(v6InputRules, stack.Rule{Target: &stack.AcceptTarget{}})
	v6OutputRules = append(v6OutputRules, stack.Rule{Target: &stack.AcceptTarget{}})

	v4Table = stack.Table{
		Rules: append(append([]stack.Rule{{Target: &stack.AcceptTarget{}}}, v4InputRules...), v4OutputRules...),
		BuiltinChains: [stack.NumHooks]int{
			stack.Prerouting:  0,
			stack.Input:       1,
			stack.Forward:     0,
			stack.Output:      1 + len(v4InputRules),
			stack.Postrouting: 0,
		},
	}
	v6Table = stack.Table{
		Rules: append(append([]stack.Rule{{Target: &stack.AcceptTarget{}}}, v6InputRules...), v6OutputRules...),
		BuiltinChains: [stack.NumHooks]int{
			stack.Prerouting:  0,
			stack.Input:       1,
			stack.Forward:     0,
			stack.Output:      1 + len(v6InputRules),
			stack.Postrouting: 0,
		},
	}
	return v4Table, v6Table, true
}
