mirror of
https://github.com/netbirdio/netbird.git
synced 2025-06-20 17:58:02 +02:00
[client] Support IP fragmentation in userspace (#3639)
This commit is contained in:
parent
4db78db49a
commit
192c97aa63
@ -658,7 +658,8 @@ func (m *Manager) dropFilter(packetData []byte, size int) bool {
|
|||||||
d := m.decoders.Get().(*decoder)
|
d := m.decoders.Get().(*decoder)
|
||||||
defer m.decoders.Put(d)
|
defer m.decoders.Put(d)
|
||||||
|
|
||||||
if !m.isValidPacket(d, packetData) {
|
valid, fragment := m.isValidPacket(d, packetData)
|
||||||
|
if !valid {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,6 +669,13 @@ func (m *Manager) dropFilter(packetData []byte, size int) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: pass fragments of routed packets to forwarder
|
||||||
|
if fragment {
|
||||||
|
m.logger.Trace("packet is a fragment: src=%v dst=%v id=%v flags=%v",
|
||||||
|
srcIP, dstIP, d.ip4.Id, d.ip4.Flags)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// For all inbound traffic, first check if it matches a tracked connection.
|
// For all inbound traffic, first check if it matches a tracked connection.
|
||||||
// This must happen before any other filtering because the packets are statefully tracked.
|
// This must happen before any other filtering because the packets are statefully tracked.
|
||||||
if m.stateful && m.isValidTrackedConnection(d, srcIP, dstIP, size) {
|
if m.stateful && m.isValidTrackedConnection(d, srcIP, dstIP, size) {
|
||||||
@ -815,17 +823,32 @@ func getPortsFromPacket(d *decoder) (srcPort, dstPort uint16) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) isValidPacket(d *decoder, packetData []byte) bool {
|
// isValidPacket checks if the packet is valid.
|
||||||
|
// It returns true, false if the packet is valid and not a fragment.
|
||||||
|
// It returns true, true if the packet is a fragment and valid.
|
||||||
|
func (m *Manager) isValidPacket(d *decoder, packetData []byte) (bool, bool) {
|
||||||
if err := d.parser.DecodeLayers(packetData, &d.decoded); err != nil {
|
if err := d.parser.DecodeLayers(packetData, &d.decoded); err != nil {
|
||||||
m.logger.Trace("couldn't decode packet, err: %s", err)
|
m.logger.Trace("couldn't decode packet, err: %s", err)
|
||||||
return false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(d.decoded) < 2 {
|
l := len(d.decoded)
|
||||||
m.logger.Trace("packet doesn't have network and transport layers")
|
|
||||||
return false
|
// L3 and L4 are mandatory
|
||||||
|
if l >= 2 {
|
||||||
|
return true, false
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
|
// Fragments are also valid
|
||||||
|
if l == 1 && d.decoded[0] == layers.LayerTypeIPv4 {
|
||||||
|
ip4 := d.ip4
|
||||||
|
if ip4.Flags&layers.IPv4MoreFragments != 0 || ip4.FragOffset != 0 {
|
||||||
|
return true, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.logger.Trace("packet doesn't have network and transport layers")
|
||||||
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) isValidTrackedConnection(d *decoder, srcIP, dstIP netip.Addr, size int) bool {
|
func (m *Manager) isValidTrackedConnection(d *decoder, srcIP, dstIP netip.Addr, size int) bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user