Skip to content

Commit

Permalink
Fix `"Error while resolving UDP address of GTP-U Peer app=NextMN-UPF …
Browse files Browse the repository at this point in the history
…error="lookup udp/%!s(int=2152): unknown port"`
  • Loading branch information
louisroyer committed Jan 13, 2025
1 parent 308e937 commit a0b986d
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 37 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.7
require (
github.com/adrg/xdg v0.5.3
github.com/google/gopacket v1.1.19
github.com/nextmn/go-pfcp-networking v0.0.42-0.20250113143454-90776d0e392b
github.com/nextmn/go-pfcp-networking v0.0.42
github.com/nextmn/logrus-formatter v0.0.1
github.com/sirupsen/logrus v1.9.3
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/nextmn/go-pfcp-networking v0.0.42-0.20250113143454-90776d0e392b h1:EsmVgMOf2EGTQbSjCw32PHUBxXc9sO/PEkmaDwAYguU=
github.com/nextmn/go-pfcp-networking v0.0.42-0.20250113143454-90776d0e392b/go.mod h1:KYoKLiltDmHL2YMU5mz2k/E1xMoz4TpmzTz6Nr5u5gA=
github.com/nextmn/go-pfcp-networking v0.0.42 h1:kYcGyIUMe/RVt3DpvDOKJt4+UbScIewDBMSQWLruusE=
github.com/nextmn/go-pfcp-networking v0.0.42/go.mod h1:KYoKLiltDmHL2YMU5mz2k/E1xMoz4TpmzTz6Nr5u5gA=
github.com/nextmn/logrus-formatter v0.0.1 h1:Bsf78jjiEESc+rV8xE6IyKj4frDPGMwXFNrLQzm6A1E=
github.com/nextmn/logrus-formatter v0.0.1/go.mod h1:vdSZ+sIcSna8vjbXkSFxsnsKHqRwaUEed4JCPcXoGyM=
github.com/pascaldekloe/goe v0.1.1 h1:Ah6WQ56rZONR3RW3qWa2NCZ6JAVvSpUcoLBaOmYFt9Q=
Expand Down
2 changes: 1 addition & 1 deletion internal/app/gtp-entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (s *Setup) createGtpUProtocolEntity(ipAddress netip.Addr) error {
defer cancel()
uConn.DisableErrorIndication()
uConn.AddHandler(message.MsgTypeTPDU, func(c gtpv1.Conn, senderAddr net.Addr, msg message.Message) error {
return tpduHandler(ipAddress.String(), c, senderAddr, msg, s.farUconnDb, s.tunInterface, s.pfcpServer)
return tpduHandler(ipAddress, c, senderAddr, msg, s.farUconnDb, s.tunInterface, s.pfcpServer)
})
if err := uConn.ListenAndServe(ctx); err != nil {
return err
Expand Down
7 changes: 6 additions & 1 deletion internal/app/tun.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package app

import (
"fmt"
"net/netip"
"strconv"

"github.com/nextmn/upf/internal/constants"
Expand All @@ -21,6 +22,10 @@ func (s *Setup) createTUNInterface() error {
if s.tunInterface == nil {
return fmt.Errorf("Tun interface has not been created")
}
var gtpEntity netip.Addr
if len(s.config.Gtpu.GTPUProtocolEntities) > 0 {
gtpEntity = s.config.Gtpu.GTPUProtocolEntities[0].Addr
}
go func() error {

for {
Expand All @@ -30,7 +35,7 @@ func (s *Setup) createTUNInterface() error {
return err
}
go func(packet []byte, db *FARAssociationDB, tuniface *water.Interface, pfcpServer *pfcp_networking.PFCPEntityUP) {
err := ipPacketHandler(packet, db, tuniface, pfcpServer)
err := ipPacketHandler(gtpEntity, packet, db, tuniface, pfcpServer)
if err != nil {
logrus.WithError(err).Debug("Drop packet")
}
Expand Down
52 changes: 20 additions & 32 deletions internal/app/up-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import (
"context"
"fmt"
"net"
"net/netip"
"strings"
"sync"

"github.com/google/gopacket"
"github.com/google/gopacket/layers"
pfcp_networking "github.com/nextmn/go-pfcp-networking/pfcp"
"github.com/nextmn/go-pfcp-networking/pfcp/api"
"github.com/nextmn/upf/internal/constants"

"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/sirupsen/logrus"
"github.com/songgao/water"
"github.com/songgao/water/waterutil"
Expand Down Expand Up @@ -55,7 +57,7 @@ func (db *FARAssociationDB) Get(seid uint64, farid uint32) *gtpv1.UPlaneConn {
return nil
}

func ipPacketHandler(packet []byte, db *FARAssociationDB, tuniface *water.Interface, pfcpServer *pfcp_networking.PFCPEntityUP) error {
func ipPacketHandler(gtpEntity netip.Addr, packet []byte, db *FARAssociationDB, tuniface *water.Interface, pfcpServer *pfcp_networking.PFCPEntityUP) error {
logrus.Debug("Received IP packet on TUN interface")
pfcpSession, err := pfcpSessionLookUp(false, 0, "", packet, pfcpServer)
if err != nil {
Expand Down Expand Up @@ -83,11 +85,11 @@ func ipPacketHandler(packet []byte, db *FARAssociationDB, tuniface *water.Interf
}
return err
}
handleIncommingPacket(db, packet, false, pfcpSession, pdr, tuniface)
handleIncommingPacket(gtpEntity, db, packet, false, pfcpSession, pdr, tuniface)
return nil
}

func tpduHandler(iface string, c gtpv1.Conn, senderAddr net.Addr, msg message.Message, db *FARAssociationDB, tuniface *water.Interface, pfcpServer *pfcp_networking.PFCPEntityUP) error {
func tpduHandler(iface netip.Addr, c gtpv1.Conn, senderAddr net.Addr, msg message.Message, db *FARAssociationDB, tuniface *water.Interface, pfcpServer *pfcp_networking.PFCPEntityUP) error {
logrus.WithFields(logrus.Fields{
"sender": senderAddr,
"teid": msg.TEID(),
Expand All @@ -99,7 +101,7 @@ func tpduHandler(iface string, c gtpv1.Conn, senderAddr net.Addr, msg message.Me
logrus.WithError(err).Error("Could not marshal GTP packet")
return err
}
pfcpSession, err := pfcpSessionLookUp(true, msg.TEID(), iface, packet, pfcpServer)
pfcpSession, err := pfcpSessionLookUp(true, msg.TEID(), iface.String(), packet, pfcpServer)
if err != nil {
logrus.WithError(err).WithFields(logrus.Fields{
"teid": msg.TEID(),
Expand All @@ -108,7 +110,7 @@ func tpduHandler(iface string, c gtpv1.Conn, senderAddr net.Addr, msg message.Me
return err
}
defer pfcpSession.RUnlock()
pdr, err := pfcpSessionPDRLookUp(pfcpSession, true, msg.TEID(), iface, packet)
pdr, err := pfcpSessionPDRLookUp(pfcpSession, true, msg.TEID(), iface.String(), packet)
if err != nil {
logrus.WithError(err).WithFields(logrus.Fields{
"teid": msg.TEID(),
Expand All @@ -121,7 +123,7 @@ func tpduHandler(iface string, c gtpv1.Conn, senderAddr net.Addr, msg message.Me
"teid": msg.TEID(),
"interface": iface,
}).Debug("Found PDR associated on this packet")
handleIncommingPacket(db, packet, true, pfcpSession, pdr, tuniface)
handleIncommingPacket(iface, db, packet, true, pfcpSession, pdr, tuniface)
return nil
}

Expand Down Expand Up @@ -199,7 +201,7 @@ func handleOuterHeaderRemoval(packet []byte, isGTP bool, outerHeaderRemoval *ie.
return packet, nil, nil
}

func handleIncommingPacket(db *FARAssociationDB, packet []byte, isGTP bool, session api.PFCPSessionInterface, pdr api.PDRInterface, tuniface *water.Interface) error {
func handleIncommingPacket(gtpIface netip.Addr, db *FARAssociationDB, packet []byte, isGTP bool, session api.PFCPSessionInterface, pdr api.PDRInterface, tuniface *water.Interface) error {
if logrus.IsLevelEnabled(logrus.TraceLevel) {
pdrid, err := pdr.ID()
if err == nil {
Expand Down Expand Up @@ -271,6 +273,10 @@ func handleIncommingPacket(db *FARAssociationDB, packet []byte, isGTP bool, sess
default:
ipAddress = ""
}
netIpAddr, err := netip.ParseAddr(ipAddress)
if err != nil {
return err
}
switch {
case ohc.HasTEID(): // Outer Header Creation
// forward over GTP/UDP/IP
Expand All @@ -280,9 +286,9 @@ func handleIncommingPacket(db *FARAssociationDB, packet []byte, isGTP bool, sess
}
tlm, err := fp.TransportLevelMarking()
if err == nil {
return forwardGTP(gpdu, ipAddress, int(tlm>>8), session, farid, db)
return forwardGTP(gtpIface, gpdu, netIpAddr, int(tlm>>8), session, farid, db)
} else {
return forwardGTP(gpdu, ipAddress, 0, session, farid, db)
return forwardGTP(gtpIface, gpdu, netIpAddr, 0, session, farid, db)
}
case ohc.HasPortNumber():
// forward over UDP/IP
Expand Down Expand Up @@ -349,21 +355,8 @@ func handleIncommingPacket(db *FARAssociationDB, packet []byte, isGTP bool, sess

}

func forwardGTP(gpdu *message.Header, ipAddress string, dscpecn int, session api.PFCPSessionInterface, farid uint32, db *FARAssociationDB) error {
if ipAddress == "" {
return fmt.Errorf("IP Address for GTP Forwarding is empty")
}
var udpaddr string
if strings.Count(ipAddress, ":") > 0 {
udpaddr = fmt.Sprintf("[%s]:%s", ipAddress, constants.GTPU_PORT)
} else {
udpaddr = fmt.Sprintf("%s:%s", ipAddress, constants.GTPU_PORT)
}
raddr, err := net.ResolveUDPAddr("udp", udpaddr)
if err != nil {
logrus.WithError(err).Error("Error while resolving UDP address of GTP-U Peer")
return err
}
func forwardGTP(gtpIface netip.Addr, gpdu *message.Header, ipAddress netip.Addr, dscpecn int, session api.PFCPSessionInterface, farid uint32, db *FARAssociationDB) error {
raddr := net.UDPAddrFromAddrPort(netip.AddrPortFrom(ipAddress, constants.GTPU_PORT))
// Check Uconn exists for this FAR
seid, err := session.LocalSEID()
if err != nil {
Expand All @@ -376,12 +369,7 @@ func forwardGTP(gpdu *message.Header, ipAddress string, dscpecn int, session api
// For the GTP-U messages described below (other than the Echo Response message, see clause 4.4.2.2), the UDP Source
// Port or the Flow Label field (see IETF RFC 6437 [37]) should be set dynamically by the sending GTP-U entity to help
// balancing the load in the transport network.
c, err := net.Dial("udp", udpaddr)
if err != nil {
return err
}
c.Close()
laddr := c.LocalAddr().(*net.UDPAddr)
laddr := net.UDPAddrFromAddrPort(netip.AddrPortFrom(gtpIface, 0))
ch := make(chan bool)
go func(ch chan bool) error {
ctx, cancel := context.WithCancel(context.Background()) // FIXME: use context
Expand Down

0 comments on commit a0b986d

Please sign in to comment.