Skip to content

Commit

Permalink
Replace N3IWF pkg to IKE pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
allen0091 committed Sep 20, 2024
1 parent 72025a1 commit d4dd815
Show file tree
Hide file tree
Showing 11 changed files with 505 additions and 612 deletions.
7 changes: 2 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ require (
github.com/calee0219/fatal v0.0.1
github.com/davecgh/go-spew v1.1.1
github.com/free5gc/aper v1.0.5
github.com/free5gc/n3iwf v1.2.2
github.com/free5gc/ike v1.0.1-0.20240918094906-1ee5ab8d45ed
github.com/free5gc/nas v1.0.7
github.com/free5gc/ngap v1.0.8
github.com/free5gc/openapi v1.0.8
github.com/free5gc/util v1.0.6
github.com/go-ping/ping v0.0.0-20211014180314-6e2b003bffdd
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1
github.com/vishvananda/netlink v1.1.0
golang.org/x/net v0.17.0
Expand All @@ -25,7 +26,6 @@ require (
github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/free5gc/sctp v1.0.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
Expand All @@ -42,16 +42,13 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/tim-ywliu/nested-logrus-formatter v1.3.2 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
github.com/wmnsk/go-gtp v0.8.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
89 changes: 2 additions & 87 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion internal/qos/qos.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package qos
import (
"errors"

"github.com/free5gc/n3iwf/pkg/ike/message"
"github.com/free5gc/ike/message"
)

type PDUQoSInfo struct {
Expand Down
11 changes: 4 additions & 7 deletions internal/util/initContext.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package util
import (
"github.com/sirupsen/logrus"

n3iwfContext "github.com/free5gc/n3iwf/pkg/context"
"github.com/free5gc/n3iwue/internal/logger"
n3ue_security "github.com/free5gc/n3iwue/internal/security"
context "github.com/free5gc/n3iwue/pkg/context"
Expand All @@ -22,12 +21,10 @@ func InitN3UEContext() {

n3ueContext.N3ueInfo = factory.N3ueConfig.Configuration.N3UEInfo
n3ueContext.N3iwfInfo = factory.N3ueConfig.Configuration.N3IWFInfo

n3ueContext.N3IWFUe = new(n3iwfContext.N3IWFIkeUe)
n3ueContext.N3IWFRanUe = new(n3iwfContext.N3IWFRanUe)
n3ueContext.N3IWFRanUe.PduSessionList = make(map[int64]*n3iwfContext.PDUSession)
n3ueContext.N3IWFUe.N3IWFChildSecurityAssociation = make(map[uint32]*n3iwfContext.ChildSecurityAssociation)
n3ueContext.N3IWFUe.TemporaryExchangeMsgIDChildSAMapping = make(map[uint32]*n3iwfContext.ChildSecurityAssociation)
n3ueContext.N3IWFRanUe = new(context.N3IWFRanUe)
n3ueContext.N3IWFUe = new(context.N3IWFIkeUe)
n3ueContext.N3IWFUe.N3IWFChildSecurityAssociation = make(map[uint32]*context.ChildSecurityAssociation)
n3ueContext.N3IWFUe.TemporaryExchangeMsgIDChildSAMapping = make(map[uint32]*context.ChildSecurityAssociation)
n3ueContext.PduSessionCount = 1

supi := n3ueContext.N3ueInfo.GetSUPI()
Expand Down
175 changes: 171 additions & 4 deletions pkg/context/context.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package context

import (
"fmt"
"math/big"
"net"

"github.com/pkg/errors"
"github.com/vishvananda/netlink"

"github.com/free5gc/n3iwf/pkg/context"
"github.com/free5gc/n3iwf/pkg/ike/message"
"github.com/free5gc/ike/message"
ike_security "github.com/free5gc/ike/security"
"github.com/free5gc/n3iwue/internal/qos"
"github.com/free5gc/n3iwue/internal/security"
"github.com/free5gc/n3iwue/pkg/factory"
"github.com/free5gc/nas/nasType"
"github.com/free5gc/ngap/ngapType"
)

var n3ueContext = N3UE{}
Expand All @@ -26,8 +29,8 @@ const (
)

type N3UE struct {
N3IWFUe *context.N3IWFIkeUe
N3IWFRanUe *context.N3IWFRanUe
N3IWFUe *N3IWFIkeUe
N3IWFRanUe *N3IWFRanUe
N3ueInfo factory.N3UEInfo
N3iwfInfo factory.N3IWFInfo
RanUeContext *security.RanUeContext
Expand Down Expand Up @@ -58,3 +61,167 @@ type N3UE struct {
func N3UESelf() *N3UE {
return &n3ueContext
}

type N3IWFIkeUe struct {
/* UE identity */
IPSecInnerIP net.IP
IPSecInnerIPAddr *net.IPAddr // Used to send UP packets to UE

/* IKE Security Association */
N3IWFIKESecurityAssociation *IKESecurityAssociation
N3IWFChildSecurityAssociation map[uint32]*ChildSecurityAssociation // inbound SPI as key

/* Temporary Mapping of two SPIs */
// Exchange Message ID(including a SPI) and ChildSA(including a SPI)
// Mapping of Message ID of exchange in IKE and Child SA when creating new child SA
TemporaryExchangeMsgIDChildSAMapping map[uint32]*ChildSecurityAssociation // Message ID as a key

/* Security */
Kn3iwf []uint8 // 32 bytes (256 bits), value is from NGAP IE "Security Key"

/* NAS IKE Connection */
IKEConnection *UDPSocketInfo

// Length of PDU Session List
PduSessionListLen int
}

type N3IWFRanUe struct {
/* UE identity */
RanUeNgapId int64
AmfUeNgapId int64
IPAddrv4 string
IPAddrv6 string
PortNumber int32
MaskedIMEISV *ngapType.MaskedIMEISV // TS 38.413 9.3.1.54
Guti string

// UE send CREATE_CHILD_SA response
TemporaryCachedNASMessage []byte

/* NAS TCP Connection Established */
IsNASTCPConnEstablished bool
IsNASTCPConnEstablishedComplete bool

/* NAS TCP Connection */
TCPConnection net.Conn

/* Others */
Guami *ngapType.GUAMI
IndexToRfsp int64
Ambr *ngapType.UEAggregateMaximumBitRate
AllowedNssai *ngapType.AllowedNSSAI
RadioCapability *ngapType.UERadioCapability // TODO: This is for RRC, can be deleted
CoreNetworkAssistanceInformation *ngapType.CoreNetworkAssistanceInformation // TS 38.413 9.3.1.15
IMSVoiceSupported int32
RRCEstablishmentCause int16
PduSessionReleaseList ngapType.PDUSessionResourceReleasedListRelRes
}

type IKESecurityAssociation struct {
*ike_security.IKESAKey
// SPI
RemoteSPI uint64
LocalSPI uint64

// Message ID
InitiatorMessageID uint32
ResponderMessageID uint32

// Authentication data
ResponderSignedOctets []byte
InitiatorSignedOctets []byte

// Used for key generating
ConcatenatedNonce []byte

// State for IKE_AUTH
State uint8

// Temporary data stored for the use in later exchange
IKEAuthResponseSA *message.SecurityAssociation
}

func (ikeSA *IKESecurityAssociation) String() string {
return "====== IKE Security Association Info =====" +
"\nInitiator's SPI: " + fmt.Sprintf("%016x", ikeSA.LocalSPI) +
"\nResponder's SPI: " + fmt.Sprintf("%016x", ikeSA.RemoteSPI) +
"\nIKESAKey: " + ikeSA.IKESAKey.String()
}

type ChildSecurityAssociation struct {
*ike_security.ChildSAKey

// SPI
InboundSPI uint32 // N3IWF Specify
OutboundSPI uint32 // Non-3GPP UE Specify

// Associated XFRM interface
XfrmIface netlink.Link

XfrmStateList []netlink.XfrmState
XfrmPolicyList []netlink.XfrmPolicy

// IP address
PeerPublicIPAddr net.IP
LocalPublicIPAddr net.IP

// Traffic selector
SelectedIPProtocol uint8
TrafficSelectorLocal net.IPNet
TrafficSelectorRemote net.IPNet

// Encapsulate
EnableEncapsulate bool
N3IWFPort int
NATPort int
}

type UDPSocketInfo struct {
Conn *net.UDPConn
N3IWFAddr *net.UDPAddr
UEAddr *net.UDPAddr
}

// When N3IWF send CREATE_CHILD_SA request to N3UE, the inbound SPI of childSA will be only stored first until
// receive response and call CompleteChildSAWithProposal to fill the all data of childSA
func (ikeUe *N3IWFIkeUe) CreateHalfChildSA(msgID, inboundSPI uint32, pduSessionID int64) {
childSA := new(ChildSecurityAssociation)
childSA.InboundSPI = inboundSPI
// Map Exchange Message ID and Child SA data until get paired response
ikeUe.TemporaryExchangeMsgIDChildSAMapping[msgID] = childSA
}

func (ikeUe *N3IWFIkeUe) CompleteChildSA(msgID uint32, outboundSPI uint32,
chosenSecurityAssociation *message.SecurityAssociation,
) (*ChildSecurityAssociation, error) {
childSA, ok := ikeUe.TemporaryExchangeMsgIDChildSAMapping[msgID]

if !ok {
return nil, errors.Errorf("CompleteChildSA(): There's not a half child SA created by the exchange with message ID %d.", msgID)
}

// Remove mapping of exchange msg ID and child SA
delete(ikeUe.TemporaryExchangeMsgIDChildSAMapping, msgID)

if chosenSecurityAssociation == nil {
return nil, errors.Errorf("CompleteChildSA(): chosenSecurityAssociation is nil")
}

if len(chosenSecurityAssociation.Proposals) == 0 {
return nil, errors.Errorf("CompleteChildSA(): No proposal")
}

childSA.OutboundSPI = outboundSPI

var err error
childSA.ChildSAKey, err = ike_security.NewChildSAKeyByProposal(chosenSecurityAssociation.Proposals[0])
if err != nil {
return nil, errors.Wrapf(err, "CompleteChildSA")
}

// Record to UE context with inbound SPI as key
ikeUe.N3IWFChildSecurityAssociation[childSA.InboundSPI] = childSA

return childSA, nil
}
29 changes: 9 additions & 20 deletions pkg/ike/dispatcher.go → pkg/ike/handler/dispatcher.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,36 @@
package ike
package handler

import (
"net"
"runtime/debug"

"github.com/sirupsen/logrus"

ike_message "github.com/free5gc/n3iwf/pkg/ike/message"
ike_message "github.com/free5gc/ike/message"
"github.com/free5gc/n3iwue/internal/logger"
"github.com/free5gc/n3iwue/pkg/ike/handler"
)

var ikeLog *logrus.Entry

func init() {
ikeLog = logger.IKELog
}

func Dispatch(udpConn *net.UDPConn, localAddr, remoteAddr *net.UDPAddr, msg []byte) {
func Dispatch(udpConn *net.UDPConn, localAddr, remoteAddr *net.UDPAddr,
ikeMessage *ike_message.IKEMessage,
) {
defer func() {
if p := recover(); p != nil {
// Print stack for panic to log. Fatalf() will let program exit.
logger.IKELog.Fatalf("panic: %v\n%s", p, string(debug.Stack()))
}
}()

ikeMessage := new(ike_message.IKEMessage)

err := ikeMessage.Decode(msg)
if err != nil {
ikeLog.Error(err)
return
}

switch ikeMessage.ExchangeType {
case ike_message.IKE_SA_INIT:
handler.HandleIKESAINIT(udpConn, localAddr, remoteAddr, ikeMessage)
HandleIKESAINIT(udpConn, localAddr, remoteAddr, ikeMessage)
case ike_message.IKE_AUTH:
handler.HandleIKEAUTH(udpConn, localAddr, remoteAddr, ikeMessage)
HandleIKEAUTH(udpConn, localAddr, remoteAddr, ikeMessage)
case ike_message.CREATE_CHILD_SA:
handler.HandleCREATECHILDSA(udpConn, localAddr, remoteAddr, ikeMessage)
HandleCREATECHILDSA(udpConn, localAddr, remoteAddr, ikeMessage)
case ike_message.INFORMATIONAL:
handler.HandleInformational(udpConn, localAddr, remoteAddr, ikeMessage)
HandleInformational(udpConn, localAddr, remoteAddr, ikeMessage)
default:
ikeLog.Warnf("Unimplemented IKE message type, exchange type: %d", ikeMessage.ExchangeType)
}
Expand Down
Loading

0 comments on commit d4dd815

Please sign in to comment.