-
Notifications
You must be signed in to change notification settings - Fork 116
Support for Multiple DNNs per Device Group with a Single UPF #929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: anaswara <anaswara.n@cdac.in>
cb22dba
to
be21356
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my preliminary testing and the changes, this PR should be independent of the other PRs you opened, correct? If so, we could proceed to merge it after the comments/suggestions have been addressed
"dnn_list": [ | ||
{ | ||
"dnn": "internet", | ||
"ue_ip_pool": "10.250.0.0/16" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that now you have the ue_ip_pool
here, should not it be removed from below?
// "hostname": "upf-0",
"ue_ip_pool": "10.250.0.0/16"
},
"dnn_list": [ | ||
{ | ||
"dnn": "internet", | ||
"ue_ip_pool": "10.250.0.0/16" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, can we please update this to use a private IP range/pool?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gab-arrobo Isn't it like 10.0.0.0/8 is complete Class A private IP address range. So 10.250.0.0/16 is part of private IP address range.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gab-arrobo Isn't it like 10.0.0.0/8 is complete Class A private IP address range. So 10.250.0.0/16 is part of private IP address range.
My bad. I misread this... for some reason I thought it was 172.250.0.0/16
(as it was in OnRamp
before). @anaswarac-dac please disregard this comment
HTTPPort string `json:"http_port"` | ||
DnnList []DNNInfo `json:"dnn_list"` | ||
EnableUeIPAlloc bool `json:"enable_ue_ip_alloc"` | ||
UEIPPool string `json:"ue_ip_pool"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that you are moving the UEIPPool
to inside DNNInfo
, should not it be removed from here?
UEIPPool string `json:"ue_ip_pool"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we should remove UEIPPool config from here and also look at the functionality of enable_ue_ip_alloc flag.
if p.UPAllocateFteid { | ||
var fteid uint32 | ||
if pConn.upf.fteidGenerator == nil { | ||
logger.PfcpLog.Warnf("fteid is nill") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logger.PfcpLog.Warnf("fteid is nill") | |
logger.PfcpLog.Warnf("fteid is nil") |
|
||
up4.ueIPPool = MustParseStrIP(conf.CPIface.UEIPPool) | ||
if len(conf.CPIface.DnnList) > 0 { | ||
up4.ueIPPool = MustParseStrIP(conf.CPIface.DnnList[0].UEIPPool) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that a device group can support multiple DNNs (which includes dnn itself and UE IP pool) but only the IP pool for the first dnn is actually used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like up4 should support multiple IP pools now ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@patriciareinoso as far as I see we do not have any active user for UP4. @gab-arrobo are you aware about any users?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we need to decide what to do with that code (whether maintain it or remove it) because, as far as I know, we are not supporting UP4 anymore. So, I would say that we should remove it. Probably this is something we should bring to the TST meeting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gab-arrobo When we added multiple DNNs, the integration test for UP4 failed.
for _, dnnInfo := range conf.CPIface.DnnList { | ||
dnns = append(dnns, dnnInfo.DNN) | ||
if ippoolCidr == "" { | ||
ippoolCidr = dnnInfo.UEIPPool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In relation to my previous comment, here it actually looks like the UE IP pool for the last DNN is used, correct? or am I overlooking something?
"dnn_list": [ | ||
{ | ||
"dnn": "internet", | ||
"ue_ip_pool": "10.250.0.0/16" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as in the other jsonc file. Should not the ue_ip_pool
be removed from below (new line 168)
UEIPPool: UEPoolUPF, | ||
DnnList: []pfcpiface.DNNInfo{ | ||
{ | ||
UEIPPool: UEPoolUPF, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why you are not setting the DNN
here?
UEIPPool: UEPoolCP, | ||
DnnList: []pfcpiface.DNNInfo{ | ||
{ | ||
UEIPPool: UEPoolCP, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why you are not setting the DNN
here?
UEIPPool: UEPoolUPF, | ||
DnnList: []pfcpiface.DNNInfo{ | ||
{ | ||
UEIPPool: UEPoolUPF, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why you are not setting the DNN
here?
ippool *IPPool | ||
peers []string | ||
dnn string | ||
dnn []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dnn []string | |
dnns []string |
i think that making it plural would represent the multiple dnns better
if err != nil { | ||
return ErrInvalidArgumentWithReason("conf.UEIPPool", conf.CPIface.UEIPPool, err.Error()) | ||
for _, dnn := range conf.CPIface.DnnList { | ||
_, _, err := net.ParseCIDR(dnn.UEIPPool) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we check that dnn is not an empty string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. It seems good idea to check the pool validity. But see we have error handling as well. so that will indirectly handle the configuration error?
"peers": ["148.162.12.214"], | ||
// [Optional] Below parameters | ||
"dnn": "internet", | ||
"dnn_list": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these parameter are marked as optionals but in pfcpiface/up4.go
there is a fatal
log if the IP pool is not present. Is the dnn_list mandatory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we set the dnn_list, should we make sure that both the dnn and ip pool are set ?
// Control plane controller settings | ||
"cpiface": { | ||
"peers": ["148.162.12.214"], | ||
// [Optional] Below parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as in ptf/config/upf.jsonc
if _, ok := validModes[conf.Mode]; !ok { | ||
return ErrInvalidArgumentWithReason("conf.Mode", conf.Mode, "invalid mode") | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in this function there are 2 checks over the DnnList
that seem redundant. One is done if EnableUeIPAlloc
is true and the other if EnableP4rt
is true.
Later on in the code, the information in DnnList
seems to be used regardless of these 2 conditions being true or false.
Should the checks be done once here in this function, even if the 2 conditions are false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please update https://github.com/omec-project/upf/blob/main/docs/configuration-guide.md
- I added some comments to better understand the approach that will be used. I have some concerns regarding the possibility of setting multiple IP pools but in fact only using one
- What happens if 2 device groups within the same network slice share the same DNN ? does it mean that they need to use the same IP pool?
2 Generic comments
|
HTTPPort string `json:"http_port"` | ||
DnnList []DNNInfo `json:"dnn_list"` | ||
EnableUeIPAlloc bool `json:"enable_ue_ip_alloc"` | ||
UEIPPool string `json:"ue_ip_pool"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we should remove UEIPPool config from here and also look at the functionality of enable_ue_ip_alloc flag.
|
||
type DNNInfo struct { | ||
DNN string `json:"dnn"` | ||
UEIPPool string `json:"ue_ip_pool"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add enable_ue_ip_alloc flag in this structure and see the flow around this flag.
if err != nil { | ||
return ErrInvalidArgumentWithReason("conf.UEIPPool", conf.CPIface.UEIPPool, err.Error()) | ||
for _, dnn := range conf.CPIface.DnnList { | ||
_, _, err := net.ParseCIDR(dnn.UEIPPool) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. It seems good idea to check the pool validity. But see we have error handling as well. so that will indirectly handle the configuration error?
|
||
// Allocate and return an id in range [minValue, maxValue] | ||
func (idGenerator *FTEIDGenerator) Allocate() (uint32, error) { | ||
if idGenerator == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is redundant. Everytime we create upf object we assign/create FTEID Generator block. Perhaps you saw crash and that is the reason you want to add this nil check. But remember there is likely chance that we are masking some other bug by adding this nil check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anaswarac-dac - please confirm why this change is needed. As I said this is likely not required. Issue could be something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right — ideally the FTEIDGenerator should never be nil, as it's initialized during UPF object creation. However, I added this nil check because during testing I encountered a crash due to a nil dereference in this function.
func (pConn *PFCPConn) associationIEs() []*ie.IE { | ||
upf := pConn.upf | ||
networkInstance := string(ie.NewNetworkInstanceFQDN(upf.dnn).Payload) | ||
networkInstance := string(ie.NewNetworkInstanceFQDN(strings.Join(upf.dnn, ",")).Payload) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please help me understand why this change is needed. It seems you are trying to add more DNNs in single message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thakurajayL ,Currently, the PFCP Association Setup Request is initiated by the SMF. The UPF responds with only one DNN. After that, no further PFCP Association Setup Request is triggered by the SMF, which means there's no opportunity to send additional DNNs separately. Because of this limitation, we include all required DNNs in a single PFCP Association Setup Request to ensure that the SMF receives the full list in one go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to know which version of 29.244 you are referring to. As specification around this area has changed drastically in release 15/16/17.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thakurajayL ,We are following 3GPP TS 29.244 v16.5.0 (Release 16), and as per this version, User Plane IP Resource Information (IE Type 116) was removed. Instead, we are required to use UE IP Address Pool Information (IE Type 123) in the PFCP Association Setup Response.
As Per Section 7.2.2.2 of the spec, this IE allows the UPF to report multiple DNN and IP pool mappings to the SMF in a single response by including multiple UE IP Address Pool Information IEs, each containing:
DNN (Network Instance),
UE IP Pool Identity,
and IP version.
This change is necessary because:
The PFCP Association Setup Request is sent only once by the SMF to the UPF.
The UPF must respond once with all supported DNNs and corresponding UE IP pools.
If we send only one DNN in the PFCP Association Setup Response, the SMF won’t be aware of other available DNNs/pools, and there's no further opportunity to send them due to the single-shot nature of the PFCP association procedure.
Spec Reference:
TS 29.244 v16.5.0, Section 6.2.6.2.2:
"Optionally one or more UE IP address Pool Information IE which contains a list of UE IP Address Pool Identities per Network Instance, S-NSSAI and IP version."
DNN | Pool | IP Version
ims | ims-pool | IPv4
internet | internet-pool | IPv4
Will Update the code based on this?
@gab-arrobo , @thakurajayL , @patriciareinoso I have made the changes based on your comments. However, I'm currently unable to build because the integration-test-up4 and integration-test-bess are failing. I'm debugging the issue and will proceed with testing using COTS UEs once it's resolved. |
@anaswarac-dac, |
📌 Description:
This PR introduces support for associating multiple DNNs to a single device group in the 5G Core, enabling flexible and scalable configurations in deployments with a single UPF.
✅ Key Highlights:
Introduced configuration support for multiple DNNs per IMSI range in the sdcore-5g-values.yml file.
Each DNN can have its own:
IP pool
MTU
DNS
UE QoS profile (including MBR uplink/downlink and traffic class)
Validated end-to-end traffic flow for both ims and internet DNNs over the same UPF.
📂 Configuration Changes (in sdcore-5g-values.yml):
✅ device-groups Section:
ip-domains list now includes multiple DNNs (ims, internet) under a single group (gnbsim-user-group1).
ip-domain-expanded changed to ip-domains
Each DNN is mapped to a different ue-ip-pool and ue-dnn-qos.
device-groups:
- name: "gnbsim-user-group1"
imsis:
- "208930100007487"
- "208930100007488"
- "208930100007489"
- "208930100007490"
- "208930100007491"
- "208930100007492"
- "208930100007493"
- "208930100007494"
- "208930100007495"
- "208930100007496"
ip-domain-name: "pool1"
ip-domains:
- dnn: ims
dns-primary: "8.8.8.8"
mtu: 1400
ue-ip-pool: "172.252.0.0/16"
ue-dnn-qos:
dnn-mbr-downlink: 2400
dnn-mbr-uplink: 1200
bitrate-unit: Kbps
traffic-class:
name: "platinum"
qci: 5
arp: 1
pdb: 100
pelr: 6
- dnn: internet
dns-primary: "10.176.0.11"
mtu: 1460
ue-ip-pool: {{ core.upf.default_upf.ue_ip_pool }}
ue-dnn-qos:
dnn-mbr-downlink: 1000
dnn-mbr-uplink: 1000
bitrate-unit: Mbps
traffic-class:
name: "platinum"
qci: 9
arp: 6
pdb: 300
pelr: 6
site-info: "enterprise"
✅ Userplane Section:
Defined dnn_list with individual DNNs and their respective ue_ip_pool.
cpiface:
dnn_list:
- dnn: "ims"
ue_ip_pool: "172.252.0.0/16"
- dnn: "internet"
ue_ip_pool: "172.250.0.0/16" # Must match slice DNN
hostname: "upf"
enable_ue_ip_alloc: false