diff options
-rw-r--r-- | pkg/tcpip/network/ipv4/ipv4.go | 12 | ||||
-rw-r--r-- | pkg/tcpip/stack/nic.go | 9 | ||||
-rw-r--r-- | pkg/tcpip/stack/registration.go | 2 |
3 files changed, 20 insertions, 3 deletions
diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index c0af9a2d8..18078c74c 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -243,8 +243,10 @@ func (e *endpoint) addIPHeader(r *stack.Route, hdr *buffer.Prependable, payloadS // WritePacket writes a packet to the given destination address and protocol. func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, params stack.NetworkHeaderParams, pkt tcpip.PacketBuffer) *tcpip.Error { - ip := e.addIPHeader(r, &pkt.Header, pkt.Data.Size(), params) - pkt.NetworkHeader = buffer.View(ip) + if !params.Forwarded { + ip := e.addIPHeader(r, &pkt.Header, pkt.Data.Size(), params) + pkt.NetworkHeader = buffer.View(ip) + } if r.Loop&stack.PacketLoop != 0 { // The inbound path expects the network header to still be in @@ -264,6 +266,12 @@ func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, params stack.Netw return nil } if pkt.Header.UsedLength()+pkt.Data.Size() > int(e.linkEP.MTU()) && (gso == nil || gso.Type == stack.GSONone) { + h := header.IPv4(pkt.Header.View()) + fmt.Println("DF: ", pkt.Header.UsedLength(), pkt.Data.Size(), e.linkEP.MTU()) + if params.Forwarded && (h.Flags() & header.IPv4FlagDontFragment) != 0 { + e.SendIcmp(pkt, header.ICMPv4DstUnreachable, header.ICMPv4FragmentationNeeded, uint16(e.linkEP.MTU())) + return nil // FIXME + } return e.writePacketFragments(r, gso, int(e.linkEP.MTU()), pkt) } if err := e.linkEP.WritePacket(r, gso, ProtocolNumber, pkt); err != nil { diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index af211f953..133e6e76b 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -1312,7 +1312,14 @@ func (n *NIC) forwardPacket(r *Route, protocol tcpip.NetworkProtocolNumber, pkt } } - if err := n.linkEP.WritePacket(r, nil /* gso */, protocol, pkt); err != nil { +// if err := n.linkEP.WritePacket(r, nil /* gso */, protocol, pkt); err != nil { + params := NetworkHeaderParams{ + Protocol: header.ICMPv4ProtocolNumber, //FIXME + TTL: 64, //FIXME + TOS: DefaultTOS, //FIXME + Forwarded: true, + } + if err := r.WritePacket(nil /* gso */, params, pkt); err != nil { r.Stats().IP.OutgoingPacketErrors.Increment() return } diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 1231dee63..5424f414c 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -215,6 +215,8 @@ type NetworkHeaderParams struct { // TOS refers to TypeOfService or TrafficClass field of the IP-header. TOS uint8 + + Forwarded bool } // NetworkEndpoint is the interface that needs to be implemented by endpoints |