PFCP in Go 3GPP流CUPSをGoで実装する

PFCP in Go 3GPP流CUPSをGoで実装する

698338416ec401bfb1c822d2e5523299?s=128

Yoshiyuki Kurauchi

June 26, 2020
Tweet

Transcript

  1. 1.

    Yoshiyuki Kurauchi / ENOG63 Meeting (2020.6.26) PFCP in Go 3GPPྲྀCUPSΛGoͰ࣮૷͢Δ

    #4G #5G #CUPS #PFCP #ϓϩτί ϧLOVE #3GPP͓ͦΖ͍͠ࢠ #ΘΓ ͱϓϩάϥϛϯάدΓ #Go #Gopher ͸͔Θ͍͍ #͓ख΍ΘΒ͔ʹ
  2. 4.

    ࣗݾ঺հ • ৬ྺ • 2013.02 - 2015.01: SES (NWӡ༻ɺݕূ΍Β) •

    2015.02 - 2018.10: ঎ࣾܥ (ςϨίϜؔ࿈੡඼ɾαʔϏε୲౰) • 2018.12 - Now: LTE over IPͳձࣾ (։ൃΛத৺ʹ͍Ζ͍Ζ) • ݴޠ • Go, Python, C/C++, Swift, etc. • ΤσΟλ͸VSCode೿ https://wmnsk.com/about/ Twitter: @wmnskdmms GitHub: @wmnsk
  3. 5.

    OSS׆ಈͳͲ • ࣗ࡞ϥΠϒϥϦ (جຊGo) • ओʹNWϓϩτίϧ • 3G > 4G

    > 5G… ϨΨγʔେ޷͖ʂ • CNF Testbedʹgo-gtp࠾༻ • ίϯτϦϏϡʔγϣϯྫ • Wireshark • Linux kernel driver (GTP-U) ͳͲ https://wmnsk.com/posts/20200116_gw-tester/ https://github.com/wmnsk
  4. 7.

    CUPSͱ͸ʁ • Control and User Plane Separation • Rel14(2017): 4G/LTE຤ظ

    ʙ Rel16(2020.4): 5G΋औΓࠐΜͰઈࢍංେԽத • 4GͰ͸్த͔Βಋೖ • 5G͔Β͸ωΠςΟϒ
  5. 8.

    CUPSͱ͸ʁ • ༻ޠ • CP/UP function: C-Planeଆϊʔυ / U-Planeଆϊʔυ •

    Association: ϊʔυؒʹ͓͚ΔϐΞϦϯά • Session: ݸผͷ੍ޚద༻୯Ґ • Rule: ੍ޚϧʔϧ (ޙड़) CP function UP function ⚠ ҎޙɺUP functionΛ౓ʑUPFͱུ͠·͕͢ɺ 5Gͷϊʔυͷ͜ͱͰ͸͋Γ·ͤΜɻ
  6. 9.

    CUPSͱ͸ʁ • ༻ޠ • CP/UP function: C-Planeଆϊʔυ / U-Planeଆϊʔυ •

    Association: ϊʔυؒʹ͓͚ΔϐΞϦϯά • Session: ݸผͷ੍ޚద༻୯Ґ • Rule: ੍ޚϧʔϧ (ޙड़) Association
  7. 10.

    CUPSͱ͸ʁ • ༻ޠ • CP/UP function: C-Planeଆϊʔυ / U-Planeଆϊʔυ •

    Association: ϊʔυؒʹ͓͚ΔϐΞϦϯά • Session: ݸผͷ੍ޚద༻୯Ґ • Rule: ੍ޚϧʔϧ (ޙड़) Session
  8. 11.

    PFCPͱ͸ʁ • Packet Forwarding Control Protocol ͷ͜ͱ • CPFͱUPFͷίϛϡχέʔγϣϯํ๏ɾखଓ͖Λنఆ •

    ؔ࿈Spec: TS 23.214(Architecture), TS 29.244(Protocol) • ౰ॳ͸EPCͰ࢖ΘΕΔI/F໊͔Β”Sx”ͱݺ͹Ε͓ͯΓɺະͩʹͦͷ໊࢒͕ࢄ ݟ͞ΕΔ
  9. 14.

    • جຊγʔέϯε • §6.2 PFCP Node Related Procedures • AssociationΛுͬͨΓ͢Δ

    • §6.3 PFCP Session Related Procedures • ηογϣϯɺ੍ޚϧʔϧΛ؅ཧ͢Δ PFCPͱ͸ʁ
  10. 15.

    • جຊγʔέϯε • §6.2 PFCP Node Related Procedures • Heartbeat

    Procedure • Load/Overload Control Procedure • PFD Management Procedure • Association Setup/Update/Release Procedure • Node Report Procedure PFCPͱ͸ʁ CPF UPF Association Setup Request Association Setup Response Heartbeat Request/Response Association Release Request Association Release Response (Session-related messages)
  11. 16.

    • جຊγʔέϯε • §6.2 PFCP Node Related Procedures • Heartbeat

    Procedure • Load/Overload Control Procedure • Overload Control Procedure • PFD Management Procedure • Association Setup/Update/Release • Node Report Procedure PFCPͱ͸ʁ CPF UPF Association Setup Request Association Setup Response Heartbeat Request/Response Association Release Request Association Release Response (Session-related messages)
  12. 17.

    • جຊγʔέϯε • §6.3 PFCP Session Related Procedures • Session

    … Procedure • Establishment • Modification • Deletion • Report PFCPͱ͸ʁ CPF UPF Session Establishment Request Session Establishment Response Session Modification Request/Response Session Deletion Request Session Deletion Response (enforcing rules) Association
  13. 18.

    • جຊγʔέϯε • §6.3 PFCP Session Related Procedures • Sessio

    • Establishment • Modification • Deletion • Report PFCPͱ͸ʁ CPF UPF Session Establishment Request Session Establishment Response Session Modification Request/Response Session Deletion Request Session Deletion Response (enforcing rules) Association
  14. 19.

    PFCPͱ͸ʁ • ͜͜ͰύέοτΛ͝ཡ͍ͩ͘͞ • Session Establishment Request • Create PDR

    • … • PDI • … • Create FAR • … https://gist.github.com/wmnsk/3e8073d3404d8eb36f33300b7a8babe5
  15. 20.

    PFCPͱ͸ʁ • ͜͜ͰύέοτΛ͝ཡ͍ͩ͘͞ • Session Establishment Request • Create PDR

    • … • PDI • … • Create FAR • … https://gist.github.com/wmnsk/3e8073d3404d8eb36f33300b7a8babe5
  16. 21.

    PFCPͱ͸ʁ • ੍ޚॲཧ • Packet Detection Rule • Forwarding Action

    Rule • Usage Reporting Rule • QoS Enforcement Rule • Buffering Action Rule • Multi-Access Rule • େ·͔ͳྲྀΕ • PDRʹج͍ͮͯύέοτΛৼΓ෼͚Δ • సૹઌΛܾΊΔ (υϩοϓͱ͔΋͋Δ) • CPF͕FARͰࢦࣔ͢Δ • UPFଆʹ͋ΔPredefinedϧʔϧΛ࢖͏ • ͦͷଞϧʔϧΛద༻͢Δ • Usage ReportɺQoS EnforcementͳͲ
  17. 22.

    PFCPͱ͸ʁ • ੍ޚॲཧ • Packet Detection Rule • Forwarding Action

    Rule • Usage Reporting Rule • QoS Enforcement Rule • Buffering Action Rule • Multi-Access Rule • ύέοτΛ෼ྨ͢ΔϧʔϧͷΑ͏ͳ΋ͷ • Outer (GTP-Uϔομ) / InnerͲͪΒ΋ݟΔ • GTPͷTEID • Flow Description ͳͲ • PDR͕ܾ·ΔͱɺFAR, URR, QER, MAR΋ Ұҙʹܾ·Δ
  18. 23.

    PFCPͱ͸ʁ • ੍ޚॲཧ • Packet Detection Rule • Forwarding Action

    Rule • Usage Reporting Rule • QoS Enforcement Rule • Buffering Action Rule • Multi-Access Rule • సૹؔ࿈ͷϧʔϧ • Drop, Forward, Buffer, DuplicateͳͲɺUPF ଆ͕औΔ΂͖ΞΫγϣϯΛܾΊΔ • Header EnrichmentͳΜ͔΋ʂ
  19. 24.

    PFCPͱ͸ʁ • ੍ޚॲཧ • Packet Detection Rule • Forwarding Action

    Rule • Usage Reporting Rule • QoS Enforcement Rule • Buffering Action Rule • Multi-Access Rule • Usage Reporting Ruleɿ • ར༻ঢ়گΛͲ͏Χ΢ϯτ͢Δ͔ • ͲͷλΠϛϯάͰϨϙʔτ͢Δ͔ ͳͲ • QoS Enforcement Ruleɿ • ଳҬ੍ޚ (MBR/GBR, Packet rate) • τϥϑΟοΫϚʔΩϯά ͳͲ
  20. 25.

    PFCPͱ͸ʁ • ੍ޚॲཧ • Packet Detection Rule • Forwarding Action

    Rule • Usage Reporting Rule • QoS Enforcement Rule • Buffering Action Rule • Multi-Access Rule • ׂѪ͠·͢ • ࡉׂ͔͍ʹɺ໘ന͘΋ͳ͍ͷͰ • ͦͯ͠ࢲ͕ͪΌΜͱΘ͔ͬͯͳ͍ͷͰ • ͦΕͧΕɺTS 29.244 5.2.4, 5.2.7Λࢀর • ͋ͱSRR(Session Reporting Rule / 5.2.8)ͳ Μ͔΋͋Γ·͢
  21. 27.

    go-pfcp: PFCP implementation in Golang • PFCPΛGoϓϩάϥϜ͔Βѻ͏ͨΊͷϥΠϒϥϦ • Message /

    IEͷϑΥʔϚοτ • ͔ΜͨΜʹύέοτΛ࡞Δ͜ͱ͕Ͱ͖Δ • TS 29.244 V16.3.1(2020-04) ࣌఺ͷ΋ͷ͢΂࣮ͯ૷ࡁΈ (ͨͿΜ) • Association / SessionΛखܰʹѻ͏ͨΊͷAPI • ઀ଓ͢ΔͨΊͷؔ਺΍ϐΞͷࣗಈ؅ཧͳͲ • Ӷҙ࣮૷தɾɾɾ https://github.com/wmnsk/go-pfcp
  22. 28.

    go-pfcp: PFCP implementation in Golang • ͳͥ࡞ͬͨͷ͔ • ͨͩͷझຯ •

    ·ͩSpec͕ൺֱతബ͔ͬͨͷͰ https://github.com/wmnsk/go-pfcp
  23. 29.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ1: ϝοηʔδͷΤϯίʔυ asr :=

    message.NewAssociationSetupRequest( ie.NewNodeID("", "", "go-pfcp.epc.3gppnetwork.org"), ie.NewRecoveryTimeStamp(time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC)), ie.NewUPFunctionFeatures(0x01, 0x02), ie.NewAlternativeSMFIPAddress(net.ParseIP("127.0.0.1"), net.ParseIP("2001::1")), ie.NewSMFSetID("go-pfcp.epc.3gppnetwork.org"), ie.NewClockDriftControlInformation( ie.NewTimeOffsetThreshold(10*time.Second), ), // … ) b, err := asr.Marshal() // serializes req into []byte n, err := udpConn.WriteTo(b, raddr) // sends serialized req over UDP
  24. 30.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ1: ϝοηʔδͷΤϯίʔυ asr :=

    message.NewAssociationSetupRequest( ie.NewNodeID("", "", "go-pfcp.epc.3gppnetwork.org"), ie.NewRecoveryTimeStamp(time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC)), ie.NewUPFunctionFeatures(0x01, 0x02), ie.NewAlternativeSMFIPAddress(net.ParseIP("127.0.0.1"), net.ParseIP("2001::1")), ie.NewSMFSetID("go-pfcp.epc.3gppnetwork.org"), ie.NewClockDriftControlInformation( ie.NewTimeOffsetThreshold(10*time.Second), ), // … ) b, err := asr.Marshal() // serializes req into []byte n, err := udpConn.WriteTo(b, raddr) // sends serialized req over UDP શͯͷmessage / IEͷίϯετϥΫλ
  25. 31.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ1: ϝοηʔδͷΤϯίʔυ asr :=

    message.NewAssociationSetupRequest( ie.NewNodeID("", "", "go-pfcp.epc.3gppnetwork.org"), ie.NewRecoveryTimeStamp(time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC)), ie.NewUPFunctionFeatures(0x01, 0x02), ie.NewAlternativeSMFIPAddress(net.ParseIP("127.0.0.1"), net.ParseIP("2001::1")), ie.NewSMFSetID("go-pfcp.epc.3gppnetwork.org"), ie.NewClockDriftControlInformation( ie.NewTimeOffsetThreshold(10*time.Second), ), // … ) b, err := asr.Marshal() // serializes req into []byte n, err := udpConn.WriteTo(b, raddr) // sends serialized req over UDP ֤छIEͷ࣋ͭ஋ͱGoͷܕ͕ରԠ (Ͱ͖Δ͚ͩ) ϓϦϛςΟϒ͚ͩͰͳ͘time.Time΍net.IPͳͲ
  26. 32.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ1: ϝοηʔδͷΤϯίʔυ asr :=

    message.NewAssociationSetupRequest( ie.NewNodeID("", "", "go-pfcp.epc.3gppnetwork.org"), ie.NewRecoveryTimeStamp(time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC)), ie.NewUPFunctionFeatures(0x01, 0x02), ie.NewAlternativeSMFIPAddress(net.ParseIP("127.0.0.1"), net.ParseIP("2001::1")), ie.NewSMFSetID("go-pfcp.epc.3gppnetwork.org"), ie.NewClockDriftControlInformation( ie.NewTimeOffsetThreshold(10*time.Second), ), // … ) b, err := asr.Marshal() // serializes req into []byte n, err := udpConn.WriteTo(b, raddr) // sends serialized req over UDP []byteܕʹγϦΞϥΠζͯ͠ૹ৴
  27. 33.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ1: ϝοηʔδͷΤϯίʔυ asr :=

    message.NewAssociationSetupRequest( ie.NewNodeID("", "", "go-pfcp.epc.3gppnetwork.org"), ie.NewRecoveryTimeStamp(time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC)), ie.NewUPFunctionFeatures(0x01, 0x02), ie.NewAlternativeSMFIPAddress(net.ParseIP("127.0.0.1"), net.ParseIP("2001::1")), ie.NewSMFSetID("go-pfcp.epc.3gppnetwork.org"), ie.NewClockDriftControlInformation( ie.NewTimeOffsetThreshold(10*time.Second), ), // … ) b, err := asr.Marshal() // serializes req into []byte n, err := udpConn.WriteTo(b, raddr) // sends serialized req over UDP ςετίʔυ͕ࢀߟʹͳΓ·͢ https://github.com/wmnsk/go-pfcp/blob/master/message/association-setup-request_test.go
  28. 34.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ2: ϝοηʔδͷσίʔυ msg, err

    := message.Unmarshal(b) asr, ok := msg.(*messages.AssociationSetupRequest) // single value IE: "go-pfcp.epc.3gppnetwork.org" in string field := asr.NodeID // accesses to a field named NodeID in AssociationSetupRequest nodeID, err := field.NodeID() // retrieves value in Go-friendly type // flags: BUCP bit is set to 1 if asr.UPFunctionFeatures.HasBUCP() { … } // complex: returns a struct named XyzFields fields, err := AlternativeSMFIPAddress() // AlternativeSMFIPAddressFields struct v4 := fields.IPv4Address // 127.0.0.1 in net.IP v6 := fields.IPv6Address // 2001::1 in net.IP
  29. 35.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ2: ϝοηʔδͷσίʔυ msg, err

    := message.Unmarshal(b) asr, ok := msg.(*messages.AssociationSetupRequest) // single value IE: "go-pfcp.epc.3gppnetwork.org" in string field := asr.NodeID // accesses to a field named NodeID in AssociationSetupRequest nodeID, err := field.NodeID() // retrieves value in Go-friendly type // flags: BUCP bit is set to 1 if asr.UPFunctionFeatures.HasBUCP() { … } // complex: returns a struct named XyzFields fields, err := AlternativeSMFIPAddress() // AlternativeSMFIPAddressFields struct v4 := fields.IPv4Address // 127.0.0.1 in net.IP v6 := fields.IPv6Address // 2001::1 in net.IP []byteΛmessage.MessageΠϯλʔϑΣΠεʹ Unmarshal → ಛఆͷϝοηʔδܕʹassert
  30. 36.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ2: ϝοηʔδͷσίʔυ msg, err

    := message.Unmarshal(b) asr, ok := msg.(*messages.AssociationSetupRequest) // single value IE: "go-pfcp.epc.3gppnetwork.org" in string field := asr.NodeID // accesses to a field named NodeID in AssociationSetupRequest nodeID, err := field.NodeID() // retrieves value in Go-friendly type // flags: BUCP bit is set to 1 if asr.UPFunctionFeatures.HasBUCP() { … } // complex: returns a struct named XyzFields fields, err := AlternativeSMFIPAddress() // AlternativeSMFIPAddressFields struct v4 := fields.IPv4Address // 127.0.0.1 in net.IP v6 := fields.IPv6Address // 2001::1 in net.IP AssociationSetupRequestͷϑΟʔϧυʹ ΞΫηε (͜ͷ࣌఺Ͱ͸*ie.IEܕ)
  31. 37.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ2: ϝοηʔδͷσίʔυ msg, err

    := message.Unmarshal(b) asr, ok := msg.(*messages.AssociationSetupRequest) // single value IE: "go-pfcp.epc.3gppnetwork.org" in string field := asr.NodeID // accesses to a field named NodeID in AssociationSetupRequest nodeID, err := field.NodeID() // retrieves value in Go-friendly type // flags: BUCP bit is set to 1 if asr.UPFunctionFeatures.HasBUCP() { … } // complex: returns a struct named XyzFields fields, err := AlternativeSMFIPAddress() // AlternativeSMFIPAddressFields struct v4 := fields.IPv4Address // 127.0.0.1 in net.IP v6 := fields.IPv6Address // 2001::1 in net.IP *ie.IEܕ͔Βɺཉ͍͠IEͷ஋ΛऔΓग़͢ (ฦΓ஋ͷܕ͸ϝιου͝ͱʹҟͳΔ) ϑϥά͸ࣗಈ൑ผ
  32. 38.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ2: ϝοηʔδͷσίʔυ msg, err

    := message.Unmarshal(b) asr, ok := msg.(*messages.AssociationSetupRequest) // single value IE: "go-pfcp.epc.3gppnetwork.org" in string field := asr.NodeID // accesses to a field named NodeID in AssociationSetupRequest nodeID, err := field.NodeID() // retrieves value in Go-friendly type // flags: BUCP bit is set to 1 if asr.UPFunctionFeatures.HasBUCP() { … } // complex: returns a struct named XyzFields fields, err := AlternativeSMFIPAddress() // AlternativeSMFIPAddressFields struct v4 := fields.IPv4Address // 127.0.0.1 in net.IP v6 := fields.IPv6Address // 2001::1 in net.IP ϑϥάͷྨ͸ɺHasSomeBit()ͰऔΓग़ͤΔ
  33. 39.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ2: ϝοηʔδͷσίʔυ msg, err

    := message.Unmarshal(b) asr, ok := msg.(*messages.AssociationSetupRequest) // single value IE: "go-pfcp.epc.3gppnetwork.org" in string field := asr.NodeID // accesses to a field named NodeID in AssociationSetupRequest nodeID, err := field.NodeID() // retrieves value in Go-friendly type // flags: BUCP bit is set to 1 if asr.UPFunctionFeatures.HasBUCP() { … } // complex: returns a struct named XyzFields fields, err := AlternativeSMFIPAddress() // AlternativeSMFIPAddressFields struct v4 := fields.IPv4Address // 127.0.0.1 in net.IP v6 := fields.IPv6Address // 2001::1 in net.IP ෳࡶͳߏ଄(ෳ਺஋)Λ࣋ͭIEͰ͸ɺstructΛฦ͢ (ͦͷதʹ֤஋͕ೖ͍ͬͯΔ)
  34. 40.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ2: ϝοηʔδͷσίʔυ msg, err

    := message.Unmarshal(b) asr, ok := msg.(*messages.AssociationSetupRequest) // single value IE: "go-pfcp.epc.3gppnetwork.org" in string field := asr.NodeID // accesses to a field named NodeID in AssociationSetupRequest nodeID, err := field.NodeID() // retrieves value in Go-friendly type // flags: BUCP bit is set to 1 if asr.UPFunctionFeatures.HasBUCP() { … } // complex: returns a struct named XyzFields fields, err := AlternativeSMFIPAddress() // AlternativeSMFIPAddressFields struct v4 := fields.IPv4Address // 127.0.0.1 in net.IP v6 := fields.IPv6Address // 2001::1 in net.IP ϑΟʔϧυ͕ົʹଟ͍IEͷྫ (ωʔϛϯά͕൒͹ϠέΫιʹͳΓ͕ͪ)
  35. 41.

    go-pfcp: PFCP implementation in Golang • ࢖͍ํ3: Association / Sessionͷ؅ཧ

    (ԾσβΠϯ / ະ࣮૷) // Client conn, err := pfcp.Dial(…) assoc, err := conn.SetupAssociation(…) session, err := assoc.EstablishSession(…) // Server conn, err := pfcp.ListenAndServe(…) assoc, err := conn.GetAssociationByAAA(…) session, err := assoc.GetSessionByBBB(…)
  36. 42.

    go-pfcp: PFCP implementation in Golang • ͭΒ͔ͬͨ͜ͱ1: ϓϩτίϧࣗମ͕݁ߏ৽͍͠ • Specͷߋ৽಺༰͕͙͍͑

    • IE͕ͨ͘͞Μ૿͑ͨΓ͢Δ • ·ͩCR͕ੵ΋͍ͬͯΔ • WiresharkཔΈ࡞ઓ͕࢖͑ͳ͍ • ࠷৽࢓༷ʹ௥͍͍͍ͭͯͳ͍(ະ࣮૷) • ͨ·ʹόά͕͋Δ(Ϣʔβ͕গͳ͍) https://code.wireshark.org/review/q/author:+Yoshiyuki+Kurauchi
  37. 44.

    go-pfcp: PFCP implementation in Golang • ࠓޙͷํ਑ • Association /

    Session؅ཧAPIͷ׬੒ • αϯϓϧΛॆ࣮ͤ͞Δ • go-gtpͱ૊Έ߹Θͤͯ؆қσϞϊʔυΛͭ͘Δ • GW TesterʹCUPSಋೖͪ͠Ό͏͔΋ʁ ͳΜ͔Star͕ ૿͑࢝Ίͨ ENOGͷ CfPక੾ ೩͑ਚ͖͍ͯΔ
  38. 45.