summaryrefslogtreecommitdiffhomepage
path: root/wgengine/netstack/netstack.go
diff options
context:
space:
mode:
Diffstat (limited to 'wgengine/netstack/netstack.go')
-rw-r--r--wgengine/netstack/netstack.go99
1 files changed, 98 insertions, 1 deletions
diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go
index c2b5d8a32..a07217770 100644
--- a/wgengine/netstack/netstack.go
+++ b/wgengine/netstack/netstack.go
@@ -771,6 +771,11 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper, gro *gro.
// Determine if we care about this local packet.
dst := p.Dst.Addr()
+ var IPServiceMappings netmap.IPServiceMappings
+ if ns.lb != nil {
+ IPServiceMappings = ns.lb.IPServiceMappings()
+ }
+ serviceName, hasIP := IPServiceMappings[dst]
switch {
case dst == serviceIP || dst == serviceIPv6:
// We want to intercept some traffic to the "service IP" (e.g.
@@ -787,6 +792,30 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper, gro *gro.
return filter.Accept, gro
}
}
+ case hasIP:
+ if p.IPProto != ipproto.TCP {
+ return filter.Accept, gro
+ }
+ // returns all configured VIP services, since the IPServiceMappings contains
+ // inactive service IPs when node hosts the service, we need to check the
+ // service is active or not before dropping the packet.
+ VIPServices := ns.lb.VIPServices()
+ serviceActive := false
+ for _, svc := range VIPServices {
+ // Even though control only send service IP down when there is a config
+ // for the service, we want to still check that the config still exists
+ // before passing the packet to netstack.
+ if svc.Name == serviceName {
+ serviceActive = svc.Active
+ }
+ }
+ if !serviceActive {
+ return filter.Accept, gro
+ }
+ if debugNetstack() {
+ ns.logf("Kevin_check: netstack: intercepting local VIP service packet: proto=%v dst=%v src=%v",
+ p.IPProto, p.Dst, p.Src)
+ }
case viaRange.Contains(dst):
// We need to handle 4via6 packets leaving the host if the via
// route is for this host; otherwise the packet will be dropped
@@ -946,6 +975,55 @@ func (ns *Impl) inject() {
inboundBuffs, inboundBuffsSizes := ns.getInjectInboundBuffsSizes()
for {
pkt := ns.linkEP.ReadContext(ns.ctx)
+ nh := pkt.NetworkHeader().Slice()
+ th := pkt.TransportHeader().Slice()
+
+ var src, dst netip.Addr
+ var sp, dp uint16
+ var syn, ack, rst bool
+
+ if len(nh) > 0 {
+ switch pkt.NetworkProtocolNumber {
+ case header.IPv4ProtocolNumber:
+ ip := header.IPv4(nh)
+
+ sa := ip.SourceAddress()
+ da := ip.DestinationAddress()
+
+ if s, ok := netip.AddrFromSlice(sa.AsSlice()); ok {
+ src = s.Unmap()
+ }
+ if d, ok := netip.AddrFromSlice(da.AsSlice()); ok {
+ dst = d.Unmap()
+ }
+
+ case header.IPv6ProtocolNumber:
+ ip := header.IPv6(nh)
+
+ sa := ip.SourceAddress()
+ da := ip.DestinationAddress()
+
+ if s, ok := netip.AddrFromSlice(sa.AsSlice()); ok {
+ src = s.Unmap()
+ }
+ if d, ok := netip.AddrFromSlice(da.AsSlice()); ok {
+ dst = d.Unmap()
+ }
+ }
+ }
+
+ if pkt.TransportProtocolNumber == header.TCPProtocolNumber && len(th) >= header.TCPMinimumSize {
+ tcp := header.TCP(th)
+ sp = tcp.SourcePort()
+ dp = tcp.DestinationPort()
+ f := tcp.Flags()
+ syn = f&header.TCPFlagSyn != 0
+ ack = f&header.TCPFlagAck != 0
+ rst = f&header.TCPFlagRst != 0
+ }
+
+ ns.logf("Kevin_check: inject: dequeued TCP syn=%v ack=%v rst=%v %v:%d -> %v:%d",
+ syn, ack, rst, src, sp, dst, dp)
if pkt == nil {
if ns.ctx.Err() != nil {
// Return without logging.
@@ -965,15 +1043,18 @@ func (ns *Impl) inject() {
// send traffic destined for the local device, hence must
// be injected 'inbound'.
sendToHost := ns.shouldSendToHost(pkt)
+ ns.logf("Kevin_check: inject: shouldSendToHost=%v", sendToHost)
// pkt has a non-zero refcount, so injection methods takes
// ownership of one count and will decrement on completion.
if sendToHost {
+ ns.logf("Kevin_check: inject: InjectInboundPacketBuffer")
if err := ns.tundev.InjectInboundPacketBuffer(pkt, inboundBuffs, inboundBuffsSizes); err != nil {
ns.logf("netstack inject inbound: %v", err)
return
}
} else {
+ ns.logf("Kevin_check: inject: InjectOutboundPacketBuffer")
if err := ns.tundev.InjectOutboundPacketBuffer(pkt); err != nil {
ns.logf("netstack inject outbound: %v", err)
return
@@ -998,12 +1079,28 @@ func (ns *Impl) shouldSendToHost(pkt *stack.PacketBuffer) bool {
return true
}
+ if ns.isVIPServiceIP(srcIP) {
+ dstIP := netip.AddrFrom4(v.DestinationAddress().As4())
+ if ns.isLocalIP(dstIP) {
+ ns.logf("Kevin_check: netstack: sending VIP service packet to host: src=%v dst=%v", srcIP, dstIP)
+ return true
+ }
+ }
+
case header.IPv6:
srcIP := netip.AddrFrom16(v.SourceAddress().As16())
if srcIP == serviceIPv6 {
return true
}
+ if ns.isVIPServiceIP(srcIP) {
+ dstIP := netip.AddrFrom16(v.DestinationAddress().As16())
+ if ns.isLocalIP(dstIP) {
+ ns.logf("Kevin_check: netstack: sending VIP service packet to host: src=%v dst=%v", srcIP, dstIP)
+ return true
+ }
+ }
+
if viaRange.Contains(srcIP) {
// Only send to the host if this 4via6 route is
// something this node handles.
@@ -1349,7 +1446,7 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
getConnOrReset := func(opts ...tcpip.SettableSocketOption) *gonet.TCPConn {
ep, err := r.CreateEndpoint(&wq)
if err != nil {
- ns.logf("CreateEndpoint error for %s: %v", stringifyTEI(reqDetails), err)
+ ns.logf("CreateEndpoint error for %s: (%T) %v", stringifyTEI(reqDetails), err, err)
r.Complete(true) // sends a RST
return nil
}