【5G核心网】free5GC SMF启动流程源码分析

PFCP 消息头

字节1 按位设置:
        - 位1: 代表 SEID 标记

        - 位2: 代表 MP 标记(message priority)

       - 位3-5: spare,发送者设置为0,接收将忽略

        - 位6-8: 版本

  字节 2 是消息类型
  字节3、4是两字节的消息长度
  可选项 SEID,占8字节
  最后3字节序列号.

                                                         Figure 7.2.2.1-1: General format of PFCP Header                                                                 

     - if S = 0, SEID field is not present, k = 0, m = 0 and n = 5;

     - if S = 1, SEID field is present, k = 1, m = 5 and n = 13.
 

    结构体 PFCP Header

type Header struct {
	Version         uint8
	MP              uint8
	S               uint8
	MessageType     MessageType
	MessageLength   uint16
	SEID            uint64
	SequenceNumber  uint32
	MessagePriority uint8
}

   UserPlaneInformation 结构体

userplane_information:
  up_nodes:
    gNB1:
      type: AN
      an_ip: 192.188.2.3
    BranchingUPF:
      type: UPF
      node_id: 10.200.200.102
      up_resource_ip: 192.188.2.2
    AnchorUPF1:
      type: UPF
      node_id: 10.200.200.101
      up_resource_ip: 192.188.2.23
    AnchorUPF2:
      type: UPF
      node_id: 10.200.200.103
      up_resource_ip: 192.188.2.24
  links:
    - A: gNB1
      B: BranchingUPF
    - A: BranchingUPF
      B: AnchorUPF1
    - A: BranchingUPF
      B: AnchorUPF2
// UserPlaneInformation describe core network userplane information
type UserPlaneInformation struct {
   UPNodes map[string]UPNode `yaml:"up_nodes"`
   Links   []UPLink          `yaml:"links"`
}

   UERoutingInfo 结构体

ueRoutingInfo:
  - SUPI: imsi-2089300007487
    AN: 10.200.200.101
    PathList:
      - DestinationIP: 60.60.0.101
        UPF: !!seq
          - BranchingUPF
          - AnchorUPF1

      - DestinationIP: 60.60.0.103
        UPF: !!seq
          - BranchingUPF
          - AnchorUPF2
type Path struct {
	DestinationIP string `yaml:"DestinationIP,omitempty"`

	DestinationPort string `yaml:"DestinationPort,omitempty"`

	UPF []string `yaml:"UPF,omitempty"`
}

type UERoutingInfo struct {
	SUPI string `yaml:"SUPI,omitempty"`

	AN string `yaml:"AN,omitempty"`

	PathList []Path `yaml:"PathList,omitempty"`
}

1. PFCP Association PFCP 关联请求

    参看: https://blog.csdn.net/zhonglinzhang/article/details/107542866 第 2.1 章节

    1.1 由 SMF 向 UPF 发起 PFCP 关联请求

      根据所有配置文件定义的 UPF 发起 PFCP 关联请求,SMF PFCP 服务端端口 8805

for _, upf := range context.SMF_Self().UserPlaneInformation.UPFs {
	addr := new(net.UDPAddr)
	addr.IP = net.IP(upf.NodeID.NodeIdValue)

	addr.Port = pfcpUdp.PFCP_PORT

	logger.AppLog.Infof("Send PFCP Association Request to UPF[%s]\n", addr.String())
	message.SendPfcpAssociationSetupRequest(addr)
}

    1.1.1 SendPfcpAssociationSetupRequest 函数

    创建 body,这里发送方未 CP 功能

    - Node ID,发送方以为的标识符

    - Recovery Time Stamp,当 CP 或 CP 已经启动的时间戳

    - UP Function Features,指示 UP 功能支持的特性(UP 发送)

    - CP Function Features,指示 CP 功能支持的特性(CP 发送)

    - User Plane IP Resource Information,包含 IPv4 / IPv6,还有 TEID,用来在 UP 分配 GTP-U F-TEID(UP 发送)

func BuildPfcpAssociationSetupRequest() (pfcp.PFCPAssociationSetupRequest, error) {
	msg := pfcp.PFCPAssociationSetupRequest{}

	msg.NodeID = &context.SMF_Self().CPNodeID

	msg.RecoveryTimeStamp = &pfcpType.RecoveryTimeStamp{
		RecoveryTimeStamp: udp.ServerStartTime,
	}

	msg.CPFunctionFeatures = &pfcpType.CPFunctionFeatures{
		SupportedFeatures: 0,
	}

	return msg, nil
}

    1.1.1.1 PFCP 消息填充

    消息类型为:PFCP_ASSOCIATION_SETUP_REQUEST,S 设置为 0

message := pfcp.Message{
	Header: pfcp.Header{
		Version:        pfcp.PfcpVersion,
		MP:             0,
		S:              pfcp.SEID_NOT_PRESENT,
		MessageType:    pfcp.PFCP_ASSOCIATION_SETUP_REQUEST,
		SequenceNumber: getSeqNumber(),
	},
	Body: pfcpMsg,
}

    1.1.2 SMF 处理 PFCP Association Response

    如果原因设置为 CauseRequestAccepted 更新 UPF 信息状态为 AssociatedSetUpSuccess

func HandlePfcpAssociationSetupResponse(msg *pfcpUdp.Message) {
	req := msg.PfcpMessage.Body.(pfcp.PFCPAssociationSetupResponse)

	nodeID := req.NodeID
	if req.Cause.CauseValue == pfcpType.CauseRequestAccepted {
		if nodeID == nil {
			logger.PfcpLog.Errorln("pfcp association needs NodeID")
			return
		}

		upf := smf_context.RetrieveUPFNodeByNodeID(*req.NodeID)
		upf.UPFStatus = smf_context.AssociatedSetUpSuccess

		if req.UserPlaneIPResourceInformation != nil {
			upf.UPIPInfo = *req.UserPlaneIPResourceInformation
			logger.PfcpLog.Infof("UPF(%s)[%s] setup association", upf.NodeID.ResolveNodeIdToIp().String(), upf.UPIPInfo.NetworkInstance)
		} else {
			logger.PfcpLog.Errorln("pfcp association setup response has no UserPlane IP Resource Information")
		}
	}
}

    NRF 中注册的 SMF

{
    "_id": ObjectId("5f1a9c2364d2e538cb1309d4"),
    "ipv4Addresses": [
        "smf"
    ],
    "smfInfo": {
        "sNssaiSmfInfoList": null
    },
    "nfServices": [
        {
            "serviceInstanceId": "e1b3436a-f9b9-4820-b075-d16fb4814ddansmf-pdusession",
            "serviceName": "nsmf-pdusession",
            "versions": [
                {
                    "expiry": "2020-07-24T08:30:27Z",
                    "apiVersionInUri": "v1",
                    "apiFullVersion": "https://smf:29502/nsmf-pdusession/v1"
                }
            ],
            "scheme": "https",
            "nfServiceStatus": "REGISTERED",
            "apiPrefix": "https://smf:29502"
        },
        {
            "serviceName": "nsmf-event-exposure",
            "versions": [
                {
                    "apiVersionInUri": "v1",
                    "apiFullVersion": "https://smf:29502/nsmf-pdusession/v1",
                    "expiry": "2020-07-24T08:30:27Z"
                }
            ],
            "scheme": "https",
            "nfServiceStatus": "REGISTERED",
            "apiPrefix": "https://smf:29502",
            "serviceInstanceId": "e1b3436a-f9b9-4820-b075-d16fb4814ddansmf-event-exposure"
        }
    ],
    "nfInstanceId": "e1b3436a-f9b9-4820-b075-d16fb4814dda",
    "nfType": "SMF",
    "nfStatus": "REGISTERED",
    "plmnList": [
        {
            "mcc": "208",
            "mnc": "93"
        }
    ]

猜你喜欢

转载自blog.csdn.net/zhonglinzhang/article/details/107554020