// Copyright 2019 The gVisor authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package iptables

import (
	"github.com/google/netstack/tcpip/buffer"
)

// A Hook specifies one of the hooks built into the network stack.
//
//                      Userspace app          Userspace app
//                            ^                      |
//                            |                      v
//                         [Input]               [Output]
//                            ^                      |
//                            |                      v
//                            |                   routing
//                            |                      |
//                            |                      v
// ----->[Prerouting]----->routing----->[Forward]---------[Postrouting]----->
type Hook uint

// These values correspond to values in include/uapi/linux/netfilter.h.
const (
	// Prerouting happens before a packet is routed to applications or to
	// be forwarded.
	Prerouting Hook = iota

	// Input happens before a packet reaches an application.
	Input

	// Forward happens once it's decided that a packet should be forwarded
	// to another host.
	Forward

	// Output happens after a packet is written by an application to be
	// sent out.
	Output

	// Postrouting happens just before a packet goes out on the wire.
	Postrouting

	// The total number of hooks.
	NumHooks
)

// A Verdict is returned by a rule's target to indicate how traversal of rules
// should (or should not) continue.
type Verdict int

const (
	// Accept indicates the packet should continue traversing netstack as
	// normal.
	Accept Verdict = iota

	// Drop inicates the packet should be dropped, stopping traversing
	// netstack.
	Drop

	// Stolen indicates the packet was co-opted by the target and should
	// stop traversing netstack.
	Stolen

	// Queue indicates the packet should be queued for userspace processing.
	Queue

	// Repeat indicates the packet should re-traverse the chains for the
	// current hook.
	Repeat

	// None indicates no verdict was reached.
	None

	// Jump indicates a jump to another chain.
	Jump

	// Continue indicates that traversal should continue at the next rule.
	Continue

	// Return indicates that traversal should return to the calling chain.
	Return
)

// IPTables holds all the tables for a netstack.
type IPTables struct {
	// Tables maps table names to tables. User tables have arbitrary names.
	Tables map[string]Table

	// Priorities maps each hook to a list of table names. The order of the
	// list is the order in which each table should be visited for that
	// hook.
	Priorities map[Hook][]string
}

// A Table defines a set of chains and hooks into the network stack. The
// currently supported tables are:
//   * nat
//   * mangle
type Table struct {
	// BuiltinChains holds the un-deletable chains built into netstack. If
	// a hook isn't present in the map, this table doesn't utilize that
	// hook.
	BuiltinChains map[Hook]Chain

	// DefaultTargets holds a target for each hook that will be executed if
	// chain traversal doesn't yield a verdict.
	DefaultTargets map[Hook]Target

	// UserChains holds user-defined chains for the keyed by name. Users
	// can give their chains arbitrary names.
	UserChains map[string]Chain

	// Chains maps names to chains for both builtin and user-defined chains.
	// Its entries point to Chains already either in BuiltinChains or
	// UserChains, and its purpose is to make looking up tables by name
	// fast.
	Chains map[string]*Chain

	// Metadata holds information about the Table that is useful to users
	// of IPTables, but not to the netstack IPTables code itself.
	metadata interface{}
}

// ValidHooks returns a bitmap of the builtin hooks for the given table.
func (table *Table) ValidHooks() uint32 {
	hooks := uint32(0)
	for hook, _ := range table.BuiltinChains {
		hooks |= 1 << hook
	}
	return hooks
}

// Metadata returns the metadata object stored in table.
func (table *Table) Metadata() interface{} {
	return table.metadata
}

// SetMetadata sets the metadata object stored in table.
func (table *Table) SetMetadata(metadata interface{}) {
	table.metadata = metadata
}

// A Chain defines a list of rules for packet processing. When a packet
// traverses a chain, it is checked against each rule until either a rule
// returns a verdict or the chain ends.
//
// By convention, builtin chains end with a rule that matches everything and
// returns either Accept or Drop. User-defined chains end with Return. These
// aren't strictly necessary here, but the iptables tool writes tables this way.
type Chain struct {
	// Name is the chain name.
	Name string

	// Rules is the list of rules to traverse.
	Rules []Rule
}

// A Rule is a packet processing rule. It consists of two pieces. First it
// contains zero or more matchers, each of which is a specification of which
// packets this rule applies to. If there are no matchers in the rule, it
// applies to any packet.
type Rule struct {
	// Matchers is the list of matchers for this rule.
	Matchers []Matcher

	// Target is the action to invoke if all the matchers match the packet.
	Target Target
}

// A Matcher is the interface for matching packets.
type Matcher interface {
	// Match returns whether the packet matches and whether the packet
	// should be "hotdropped", i.e. dropped immediately. This is usually
	// used for suspicious packets.
	Match(hook Hook, packet buffer.VectorisedView, interfaceName string) (matches bool, hotdrop bool)
}

// A Target is the interface for taking an action for a packet.
type Target interface {
	// Action takes an action on the packet and returns a verdict on how
	// traversal should (or should not) continue. If the return value is
	// Jump, it also returns the name of the chain to jump to.
	Action(packet buffer.VectorisedView) (Verdict, string)
}
