blob: 2ffb55f2a0e08ab2fda127d0e12da5325e7e9726 [file] [log] [blame]
// 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 stack
import (
"gvisor.dev/gvisor/pkg/tcpip"
)
// 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 RuleVerdict is what a rule decides should be done with a packet.
type RuleVerdict int
const (
// RuleAccept indicates the packet should continue through netstack.
RuleAccept RuleVerdict = iota
// RuleDrop indicates the packet should be dropped.
RuleDrop
// RuleJump indicates the packet should jump to another chain.
RuleJump
// RuleReturn indicates the packet should return to the previous chain.
RuleReturn
)
// 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. It is
// really just a list of rules with some metadata for entrypoints and such.
type Table struct {
// Rules holds the rules that make up the table.
Rules []Rule
// BuiltinChains maps builtin chains to their entrypoint rule in Rules.
BuiltinChains map[Hook]int
// Underflows maps builtin chains to their underflow rule in Rules
// (i.e. the rule to execute if the chain returns without a verdict).
Underflows map[Hook]int
// UserChains holds user-defined chains for the keyed by name. Users
// can give their chains arbitrary names.
UserChains map[string]int
// 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 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 {
// Filter holds basic IP filtering fields common to every rule.
Filter IPHeaderFilter
// 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
}
// IPHeaderFilter holds basic IP filtering data common to every rule.
type IPHeaderFilter struct {
// Protocol matches the transport protocol.
Protocol tcpip.TransportProtocolNumber
// Dst matches the destination IP address.
Dst tcpip.Address
// DstMask masks bits of the destination IP address when comparing with
// Dst.
DstMask tcpip.Address
// DstInvert inverts the meaning of the destination IP check, i.e. when
// true the filter will match packets that fail the destination
// comparison.
DstInvert bool
}
// A Matcher is the interface for matching packets.
type Matcher interface {
// Name returns the name of the Matcher.
Name() string
// Match returns whether the packet matches and whether the packet
// should be "hotdropped", i.e. dropped immediately. This is usually
// used for suspicious packets.
//
// Precondition: packet.NetworkHeader is set.
Match(hook Hook, packet PacketBuffer, 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 index of the rule to jump to.
Action(packet PacketBuffer) (RuleVerdict, int)
}