Pass AddressableEndpoint to IPTables
...instead of an address. This allows a later change to more precisely select an address based on the NAT type (source vs. destination NAT). PiperOrigin-RevId: 398559901
This commit is contained in:
parent
1df5ad1c7a
commit
8627db006b
|
@ -647,7 +647,7 @@ func (jt *JumpTarget) id() targetID {
|
|||
}
|
||||
|
||||
// Action implements stack.Target.Action.
|
||||
func (jt *JumpTarget) Action(*stack.PacketBuffer, *stack.ConnTrack, stack.Hook, *stack.Route, tcpip.Address) (stack.RuleVerdict, int) {
|
||||
func (jt *JumpTarget) Action(*stack.PacketBuffer, *stack.ConnTrack, stack.Hook, *stack.Route, stack.AddressableEndpoint) (stack.RuleVerdict, int) {
|
||||
return stack.RuleJump, jt.RuleNum
|
||||
}
|
||||
|
||||
|
|
|
@ -841,7 +841,7 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
|
|||
|
||||
// Loopback traffic skips the prerouting chain.
|
||||
inNicName := e.protocol.stack.FindNICNameFromID(e.nic.ID())
|
||||
if ok := e.protocol.stack.IPTables().CheckPrerouting(pkt, e.MainAddress().Address, inNicName); !ok {
|
||||
if ok := e.protocol.stack.IPTables().CheckPrerouting(pkt, e, inNicName); !ok {
|
||||
// iptables is telling us to drop the packet.
|
||||
stats.IPTablesPreroutingDropped.Increment()
|
||||
return
|
||||
|
|
|
@ -1100,7 +1100,7 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
|
|||
|
||||
// Loopback traffic skips the prerouting chain.
|
||||
inNicName := e.protocol.stack.FindNICNameFromID(e.nic.ID())
|
||||
if ok := e.protocol.stack.IPTables().CheckPrerouting(pkt, e.MainAddress().Address, inNicName); !ok {
|
||||
if ok := e.protocol.stack.IPTables().CheckPrerouting(pkt, e, inNicName); !ok {
|
||||
// iptables is telling us to drop the packet.
|
||||
stats.IPTablesPreroutingDropped.Increment()
|
||||
return
|
||||
|
|
|
@ -270,8 +270,8 @@ const (
|
|||
// must be dropped if false is returned.
|
||||
//
|
||||
// Precondition: The packet's network and transport header must be set.
|
||||
func (it *IPTables) CheckPrerouting(pkt *PacketBuffer, preroutingAddr tcpip.Address, inNicName string) bool {
|
||||
return it.check(Prerouting, pkt, nil /* route */, preroutingAddr, inNicName, "" /* outNicName */)
|
||||
func (it *IPTables) CheckPrerouting(pkt *PacketBuffer, addressEP AddressableEndpoint, inNicName string) bool {
|
||||
return it.check(Prerouting, pkt, nil /* route */, addressEP, inNicName, "" /* outNicName */)
|
||||
}
|
||||
|
||||
// CheckInput performs the input hook on the packet.
|
||||
|
@ -281,7 +281,7 @@ func (it *IPTables) CheckPrerouting(pkt *PacketBuffer, preroutingAddr tcpip.Addr
|
|||
//
|
||||
// Precondition: The packet's network and transport header must be set.
|
||||
func (it *IPTables) CheckInput(pkt *PacketBuffer, inNicName string) bool {
|
||||
return it.check(Input, pkt, nil /* route */, "" /* preroutingAddr */, inNicName, "" /* outNicName */)
|
||||
return it.check(Input, pkt, nil /* route */, nil /* addressEP */, inNicName, "" /* outNicName */)
|
||||
}
|
||||
|
||||
// CheckForward performs the forward hook on the packet.
|
||||
|
@ -291,7 +291,7 @@ func (it *IPTables) CheckInput(pkt *PacketBuffer, inNicName string) bool {
|
|||
//
|
||||
// Precondition: The packet's network and transport header must be set.
|
||||
func (it *IPTables) CheckForward(pkt *PacketBuffer, inNicName, outNicName string) bool {
|
||||
return it.check(Forward, pkt, nil /* route */, "" /* preroutingAddr */, inNicName, outNicName)
|
||||
return it.check(Forward, pkt, nil /* route */, nil /* addressEP */, inNicName, outNicName)
|
||||
}
|
||||
|
||||
// CheckOutput performs the output hook on the packet.
|
||||
|
@ -301,7 +301,7 @@ func (it *IPTables) CheckForward(pkt *PacketBuffer, inNicName, outNicName string
|
|||
//
|
||||
// Precondition: The packet's network and transport header must be set.
|
||||
func (it *IPTables) CheckOutput(pkt *PacketBuffer, r *Route, outNicName string) bool {
|
||||
return it.check(Output, pkt, r, "" /* preroutingAddr */, "" /* inNicName */, outNicName)
|
||||
return it.check(Output, pkt, r, nil /* addressEP */, "" /* inNicName */, outNicName)
|
||||
}
|
||||
|
||||
// CheckPostrouting performs the postrouting hook on the packet.
|
||||
|
@ -311,7 +311,7 @@ func (it *IPTables) CheckOutput(pkt *PacketBuffer, r *Route, outNicName string)
|
|||
//
|
||||
// Precondition: The packet's network and transport header must be set.
|
||||
func (it *IPTables) CheckPostrouting(pkt *PacketBuffer, r *Route, outNicName string) bool {
|
||||
return it.check(Postrouting, pkt, r, "" /* preroutingAddr */, "" /* inNicName */, outNicName)
|
||||
return it.check(Postrouting, pkt, r, nil /* addressEP */, "" /* inNicName */, outNicName)
|
||||
}
|
||||
|
||||
// check runs pkt through the rules for hook. It returns true when the packet
|
||||
|
@ -319,7 +319,7 @@ func (it *IPTables) CheckPostrouting(pkt *PacketBuffer, r *Route, outNicName str
|
|||
// dropped.
|
||||
//
|
||||
// Precondition: The packet's network and transport header must be set.
|
||||
func (it *IPTables) check(hook Hook, pkt *PacketBuffer, r *Route, preroutingAddr tcpip.Address, inNicName, outNicName string) bool {
|
||||
func (it *IPTables) check(hook Hook, pkt *PacketBuffer, r *Route, addressEP AddressableEndpoint, inNicName, outNicName string) bool {
|
||||
if pkt.NetworkProtocolNumber != header.IPv4ProtocolNumber && pkt.NetworkProtocolNumber != header.IPv6ProtocolNumber {
|
||||
return true
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ func (it *IPTables) check(hook Hook, pkt *PacketBuffer, r *Route, preroutingAddr
|
|||
table = it.v4Tables[tableID]
|
||||
}
|
||||
ruleIdx := table.BuiltinChains[hook]
|
||||
switch verdict := it.checkChain(hook, pkt, table, ruleIdx, r, preroutingAddr, inNicName, outNicName); verdict {
|
||||
switch verdict := it.checkChain(hook, pkt, table, ruleIdx, r, addressEP, inNicName, outNicName); verdict {
|
||||
// If the table returns Accept, move on to the next table.
|
||||
case chainAccept:
|
||||
continue
|
||||
|
@ -361,7 +361,7 @@ func (it *IPTables) check(hook Hook, pkt *PacketBuffer, r *Route, preroutingAddr
|
|||
// Any Return from a built-in chain means we have to
|
||||
// call the underflow.
|
||||
underflow := table.Rules[table.Underflows[hook]]
|
||||
switch v, _ := underflow.Target.Action(pkt, &it.connections, hook, r, preroutingAddr); v {
|
||||
switch v, _ := underflow.Target.Action(pkt, &it.connections, hook, r, addressEP); v {
|
||||
case RuleAccept:
|
||||
continue
|
||||
case RuleDrop:
|
||||
|
@ -453,7 +453,7 @@ func (it *IPTables) CheckPostroutingPackets(pkts PacketBufferList, r *Route, out
|
|||
func (it *IPTables) checkPackets(hook Hook, pkts PacketBufferList, r *Route, outNicName string) (drop map[*PacketBuffer]struct{}, natPkts map[*PacketBuffer]struct{}) {
|
||||
for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() {
|
||||
if !pkt.NatDone {
|
||||
if ok := it.check(hook, pkt, r, "" /* preroutingAddr */, "" /* inNicName */, outNicName); !ok {
|
||||
if ok := it.check(hook, pkt, r, nil /* addressEP */, "" /* inNicName */, outNicName); !ok {
|
||||
if drop == nil {
|
||||
drop = make(map[*PacketBuffer]struct{})
|
||||
}
|
||||
|
@ -473,11 +473,11 @@ func (it *IPTables) checkPackets(hook Hook, pkts PacketBufferList, r *Route, out
|
|||
// Preconditions:
|
||||
// * pkt is a IPv4 packet of at least length header.IPv4MinimumSize.
|
||||
// * pkt.NetworkHeader is not nil.
|
||||
func (it *IPTables) checkChain(hook Hook, pkt *PacketBuffer, table Table, ruleIdx int, r *Route, preroutingAddr tcpip.Address, inNicName, outNicName string) chainVerdict {
|
||||
func (it *IPTables) checkChain(hook Hook, pkt *PacketBuffer, table Table, ruleIdx int, r *Route, addressEP AddressableEndpoint, inNicName, outNicName string) chainVerdict {
|
||||
// Start from ruleIdx and walk the list of rules until a rule gives us
|
||||
// a verdict.
|
||||
for ruleIdx < len(table.Rules) {
|
||||
switch verdict, jumpTo := it.checkRule(hook, pkt, table, ruleIdx, r, preroutingAddr, inNicName, outNicName); verdict {
|
||||
switch verdict, jumpTo := it.checkRule(hook, pkt, table, ruleIdx, r, addressEP, inNicName, outNicName); verdict {
|
||||
case RuleAccept:
|
||||
return chainAccept
|
||||
|
||||
|
@ -494,7 +494,7 @@ func (it *IPTables) checkChain(hook Hook, pkt *PacketBuffer, table Table, ruleId
|
|||
ruleIdx++
|
||||
continue
|
||||
}
|
||||
switch verdict := it.checkChain(hook, pkt, table, jumpTo, r, preroutingAddr, inNicName, outNicName); verdict {
|
||||
switch verdict := it.checkChain(hook, pkt, table, jumpTo, r, addressEP, inNicName, outNicName); verdict {
|
||||
case chainAccept:
|
||||
return chainAccept
|
||||
case chainDrop:
|
||||
|
@ -520,7 +520,7 @@ func (it *IPTables) checkChain(hook Hook, pkt *PacketBuffer, table Table, ruleId
|
|||
// Preconditions:
|
||||
// * pkt is a IPv4 packet of at least length header.IPv4MinimumSize.
|
||||
// * pkt.NetworkHeader is not nil.
|
||||
func (it *IPTables) checkRule(hook Hook, pkt *PacketBuffer, table Table, ruleIdx int, r *Route, preroutingAddr tcpip.Address, inNicName, outNicName string) (RuleVerdict, int) {
|
||||
func (it *IPTables) checkRule(hook Hook, pkt *PacketBuffer, table Table, ruleIdx int, r *Route, addressEP AddressableEndpoint, inNicName, outNicName string) (RuleVerdict, int) {
|
||||
rule := table.Rules[ruleIdx]
|
||||
|
||||
// Check whether the packet matches the IP header filter.
|
||||
|
@ -543,7 +543,7 @@ func (it *IPTables) checkRule(hook Hook, pkt *PacketBuffer, table Table, ruleIdx
|
|||
}
|
||||
|
||||
// All the matchers matched, so run the target.
|
||||
return rule.Target.Action(pkt, &it.connections, hook, r, preroutingAddr)
|
||||
return rule.Target.Action(pkt, &it.connections, hook, r, addressEP)
|
||||
}
|
||||
|
||||
// OriginalDst returns the original destination of redirected connections. It
|
||||
|
|
|
@ -29,7 +29,7 @@ type AcceptTarget struct {
|
|||
}
|
||||
|
||||
// Action implements Target.Action.
|
||||
func (*AcceptTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, tcpip.Address) (RuleVerdict, int) {
|
||||
func (*AcceptTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, AddressableEndpoint) (RuleVerdict, int) {
|
||||
return RuleAccept, 0
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ type DropTarget struct {
|
|||
}
|
||||
|
||||
// Action implements Target.Action.
|
||||
func (*DropTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, tcpip.Address) (RuleVerdict, int) {
|
||||
func (*DropTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, AddressableEndpoint) (RuleVerdict, int) {
|
||||
return RuleDrop, 0
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ type ErrorTarget struct {
|
|||
}
|
||||
|
||||
// Action implements Target.Action.
|
||||
func (*ErrorTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, tcpip.Address) (RuleVerdict, int) {
|
||||
func (*ErrorTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, AddressableEndpoint) (RuleVerdict, int) {
|
||||
log.Debugf("ErrorTarget triggered.")
|
||||
return RuleDrop, 0
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ type UserChainTarget struct {
|
|||
}
|
||||
|
||||
// Action implements Target.Action.
|
||||
func (*UserChainTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, tcpip.Address) (RuleVerdict, int) {
|
||||
func (*UserChainTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, AddressableEndpoint) (RuleVerdict, int) {
|
||||
panic("UserChainTarget should never be called.")
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ type ReturnTarget struct {
|
|||
}
|
||||
|
||||
// Action implements Target.Action.
|
||||
func (*ReturnTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, tcpip.Address) (RuleVerdict, int) {
|
||||
func (*ReturnTarget) Action(*PacketBuffer, *ConnTrack, Hook, *Route, AddressableEndpoint) (RuleVerdict, int) {
|
||||
return RuleReturn, 0
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ type RedirectTarget struct {
|
|||
}
|
||||
|
||||
// Action implements Target.Action.
|
||||
func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, r *Route, address tcpip.Address) (RuleVerdict, int) {
|
||||
func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, r *Route, addressEP AddressableEndpoint) (RuleVerdict, int) {
|
||||
// Sanity check.
|
||||
if rt.NetworkProtocol != pkt.NetworkProtocolNumber {
|
||||
panic(fmt.Sprintf(
|
||||
|
@ -117,6 +117,7 @@ func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, r
|
|||
|
||||
// Change the address to loopback (127.0.0.1 or ::1) in Output and to
|
||||
// the primary address of the incoming interface in Prerouting.
|
||||
var address tcpip.Address
|
||||
switch hook {
|
||||
case Output:
|
||||
if pkt.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
||||
|
@ -125,7 +126,8 @@ func (rt *RedirectTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, r
|
|||
address = header.IPv6Loopback
|
||||
}
|
||||
case Prerouting:
|
||||
// No-op, as address is already set correctly.
|
||||
// addressEP is expected to be set for the prerouting hook.
|
||||
address = addressEP.MainAddress().Address
|
||||
default:
|
||||
panic("redirect target is supported only on output and prerouting hooks")
|
||||
}
|
||||
|
@ -180,7 +182,7 @@ type SNATTarget struct {
|
|||
}
|
||||
|
||||
// Action implements Target.Action.
|
||||
func (st *SNATTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, r *Route, address tcpip.Address) (RuleVerdict, int) {
|
||||
func (st *SNATTarget) Action(pkt *PacketBuffer, ct *ConnTrack, hook Hook, r *Route, _ AddressableEndpoint) (RuleVerdict, int) {
|
||||
// Sanity check.
|
||||
if st.NetworkProtocol != pkt.NetworkProtocolNumber {
|
||||
panic(fmt.Sprintf(
|
||||
|
|
|
@ -352,5 +352,5 @@ 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(*PacketBuffer, *ConnTrack, Hook, *Route, tcpip.Address) (RuleVerdict, int)
|
||||
Action(*PacketBuffer, *ConnTrack, Hook, *Route, AddressableEndpoint) (RuleVerdict, int)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue