Skip to content
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

Resolving ueAddr ambiguity when it is the UE private address #34

Closed
eric-murray opened this issue Aug 5, 2022 · 57 comments · Fixed by #139
Closed

Resolving ueAddr ambiguity when it is the UE private address #34

eric-murray opened this issue Aug 5, 2022 · 57 comments · Fixed by #139
Assignees
Labels

Comments

@eric-murray
Copy link
Collaborator

The current QoD API definitions identify the UE by its source IP address (ueAddr). If that address is public (i.e. routable) then knowledge of any UE source port (via the uePorts parameter) will allow the UE to be uniquely identified, albeit that this is not trivial. So if the specified UE source IP address is public, uePorts becomes a mandatory additional parameter.

But if the UE source IP address is private (i.e. non-routable), then it may not be possible to uniquely identify the UE. This is because the private address is allocated by the PDN GW to which the UE is connected, and a typical mobile network will have several of these with the specific PDN GW being selected based on network routing policies. PDN GWs will typically use the same private address space (usually the 10.0.0.0/8 range) which means that it is possible that more than one UE is currently allocated a given private IP address.

For the T8 interface, 3GPP resolve this ambiguity by requiring that an ipDomain parameter is also specified. This parameter resolves the ambiguity by identifying which PDN GW (i.e. which "domain") has allocated the private IP address. But I don't think CAMARA can adopt this solution as the API consumer is unlikely to know this information.

If the API consumer is the UE itself, then other approaches can be used to uniquely identify the UE, such as OpenID connect or the public source IP that will be seen by the API gateway even if not explicitly sent as an API parameter. And when the agreed proposal to allow use of GPSI as a UE identifier is implemented, then that can be specified rather than the UE source IP address.

But if the only identifying parameter for the UE is the private source IP address, then either a mechanism to resolve this ambiguity must be introduced by CAMARA, or the documentation should make clear that specifying a private IP for ueAddr is likely to result in an error response (probably 400 BAD REQUEST). Unfortunately I don't have a good proposal as to how this ambiguity can be resolved, so Vodafone's current position is that we will return an error message if the UE source IP specified is private.

@hdamker
Copy link
Collaborator

hdamker commented Aug 8, 2022

Depending on outcome of the discussion/issue the API documentation need to be updated (see #17 (comment))

@eric-murray
Copy link
Collaborator Author

We can derive the ipDomain from the UE public IP address if known. This is much simpler than trying to derive the UE identity itself from the public IP + port, but requires the API to know both the private and public UE IP to identify the UE. If it is the UE itself calling the API, then the public IP can be determined from the source IP of that request. But otherwise that parameter needs to be passed explicitly along with the private IP.

I'd propose that the ueAddr parameter be replaced by two separate optional parameters uePublicAddr and uePrivateAddr (or equivalent, if our terminology is updated). The API caller could then provide either none, one or both of these parameters, depending on their knowledge.

@hdamker hdamker assigned hdamker and eric-murray and unassigned hdamker Oct 21, 2022
@eric-murray
Copy link
Collaborator Author

eric-murray commented Nov 17, 2022

I was waiting until PR #67 was resolved before proposing changes, but I'll make a proposal here before creating a new PR. I propose to modify the current UEId schema to the following:

UeId:
  type: object
  minProperties: 1
  properties:
    externalId:
      $ref: "#/components/schemas/ExternalId"
    msisdn:
      $ref: "#/components/schemas/MSISDN"
    publicipv4addr:
      $ref: "#/components/schemas/Ipv4Addr"
    privateipv4addr:
      $ref: "#/components/schemas/Ipv4Addr"
    ipv6addr:
      $ref: "#/components/schemas/Ipv6Addr"
  description: User equipment identifier

Usage guide:

  • privateipv4addr is only generally useful if publicipv4addr is also specified
  • if publicipv4addr is specified, then privateipv4addr and/or at least one uePorts value must be specified

Some comments on property name styles would be useful as we already have a mix of styles in use (e.g. should externalId be externalid?)

@jlurien
Copy link
Collaborator

jlurien commented Nov 18, 2022

Thank you @eric-murray,

We think that adding more options to identify the UE is adding more complexity for both the consumers and the providers of the API. Providers should support all of them or relay on errors for not supported options, and consumers have to use all options simultaneously or invoke each provider in a different way.

As you know, TEF is promoting via commonalities Issue #101, the use of a universal identifier which can be obtained from the public IP and port, and used in every API. This is still under discussion but the outcome of it would impact how the UE is identified.

About the topic of private addresses, in our scenarios, we are only considering public IP addresses, and then the port becomes required. Is there a use case to include a private address? If the API consumer is an intermediary, it will see the public ip and port, and not the private address. If it is the UE itself, the private address is not enough as you say, but it is not straightforward for a UE to know its public address (it requires some service in the public internet).

Regarding the design, it would make sense to us to include both (public) ip_address and port, in the context of UE identification, within the same object. Also, when referring to IP Addresses, we may consider allowing both IPv4 and IPv6 addresses being used as value for any generic ip_address, as server does not need to be told explicitly about the format. But, as said before, we think that is better to decouple device identification to a previous step and use another universal identifier in the API.

@eric-murray
Copy link
Collaborator Author

Hi @jlurien
So, yes, I'm aware of Commonalities #101, but don't think we should necessarily suspend all discussion on UE identification until that is resolved and a common approach approved. Obviously, once a common scheme for identifying UEs is agreed, then all APIs need to be revisited.

On the issue of whether the private UE IP should be accepted as a UE identifier, my view is that this should be accepted if known to the API caller because private IP and IP domain can be used to identify the UE to the NEF whereas public IP and port cannot. The reason for introducing publicipv4addr as an identifier is to identify the IP domain, of course.

Until your comment, nobody had said that the QoD API should not accept private IP as a UE identifier, and the current API allows this. But on its own, it is ambiguous. So either additional parameters are required to resolve this ambiguity (I propose public IP address) or this scenario needs to be excluded. The views of other QoD participants would be appreciated.

Proposals to include UE port(s) within the UeId object is a separate issue to this one.

@jlurien
Copy link
Collaborator

jlurien commented Nov 18, 2022

On the issue of whether the private UE IP should be accepted as a UE identifier, my view is that this should be accepted if known to the API caller because private IP and IP domain can be used to identify the UE to the NEF whereas public IP and port cannot. The reason for introducing publicipv4addr as an identifier is to identify the IP domain, of course.

Sorry, but I don't fully understand the use case, that was my point. In which case a caller would know both the private and public addresses but it is not able to identify the UE with public address and port? Is this a limitation raised by some participant?

Until your comment, nobody had said that the QoD API should not accept private IP as a UE identifier, and the current API allows this. But on its own, it is ambiguous. So either additional parameters are required to resolve this ambiguity (I propose public IP address) or this scenario needs to be excluded. The views of other QoD participants would be appreciated.

I agree that the current API is ambiguous and we should work to document the use of the API properly. If nobody requires a private address to be specified in any case, we should make it clear and exclude that possibility.

Proposals to include UE port(s) within the UeId object is a separate issue to this one.

Agree

@eric-murray
Copy link
Collaborator Author

Well, there are techniques that allow a UE to determine their public IP address, but not the port. For example:

$ nslookup myip.opendns.com. resolver1.opendns.com

So it is possible that public IP is known but port is not. Even if the public port is known, then it will not necessarily be the port seen by the application server or the API gateway. Whilst mobile operators usually use PBA for CGNAT, and hence a given public IP and port tend to be allocated to a given UE for a reasonable period of time (even if not currently in use), purely dynamic allocation is possible. In that case public IP and port information obtained from a 3rd party service may be in use by a different UE by the time the information is passed to the API. But for identifying the IP domain, any public IP that was recently used by the UE would still identify that, even if currently allocated to a different UE.

So there are indeed scenarios where the UE would know its private and public IP, but not the public port seen by the application server or API gateway. Whether this use case would be common or not is not the question. The question is do we support it or not.

@jlurien
Copy link
Collaborator

jlurien commented Nov 18, 2022

Thank you Eric for the detailed explanation. In the end that is the question. As this issue was raised some months ago I'm not aware of the context, that's why I wondered about whether this proposal tackles a limitation or necessity raised by some participant in the short term. In our scenarios we do not foresee the UE to call the API directly.

@eric-murray
Copy link
Collaborator Author

Even if the UE does not call the API directly, it can still pass parameters to an application server for identification. It is simple for any 3rd party UE application to determine both its private and public IP, but try asking iOS for your MSISDN.

@eric-murray
Copy link
Collaborator Author

As discussed on the call today, I'll raise a PR for the above solution once PR #67 is resolved. I'll also migrate the uePorts field into the UEId object, and add some documentation on how the different IP and port fields should be used.

@eric-murray
Copy link
Collaborator Author

eric-murray commented Jan 20, 2023

In anticipation of pushing the necessary changes to v0.10.0, I thought I'd outline how I intend to approach this. I'm going to modify the ipv4addr field of the UeId object to require either a private IPv4 address or public port to be specified in addition to the public IPv4 address.

So the UeId would be modified to be:

UeId:
  type: object
  minProperties: 1
  properties:
    externalId:
      $ref: "#/components/schemas/ExternalId"
    msisdn:
      $ref: "#/components/schemas/MSISDN"
    ipv4addr:
      $ref: "#/components/schemas/UEIpv4Addr"
    ipv6addr:
      $ref: "#/components/schemas/Ipv6Addr"
  description: User equipment identifier

and a new object UEIpv4Addr would be defined as follows:

UEIpv4Addr:
  type: object
  properties:
    public_address:
      description: |
        The public IP address currently allocated to the UE by CGNAT. This is dynamic and will change over time, so it is important to specify the currently allocated public address.
      $ref: "#/components/schemas/Ipv4Addr"
    additional_info:
      type: object
      minProperties: 1
      properties:
        private_address:
          description: The private IP address allocated to the UE
          $ref: "#/components/schemas/Ipv4Addr"
        public_port:
          description: |
            Any public port currently allocated to the UE by CGNAT. These are allocated dynamically and will change over time, so it is important to specify a currently allocated public port. Note that the private port being used by the UE is not useful.
          $ref: "#/components/schemas/Port"
  required:
      - public_address
      - additional_info

The uePorts field in the CreateSession object would be deleted.

@eric-murray
Copy link
Collaborator Author

I was also thinking about possible errors that the client could then make when constructing the UeId object; The list I have so far is:

  • Insufficient properties specified (at least one identifier must be specified)
  • Invalid formatting of any specified property (i.e. not complying with the defined pattern)
  • If ipv4addr is specified then:
    • Missing or invalid public_address
    • Missing or invalid additonal_info
    • Insufficient properties specified within additional_info
    • Invalid private_address within additional_info (not compliant with pattern)
    • Invalid public_port value within additional_info (value out of range)
  • Multiple inconstant properties specified (supplied identifiers identify different UEs)
  • No UE can be identified from the specified identifiers (e.g. MSISDN is not a customer of the API provider)

Let me know of any more

@jlurien
Copy link
Collaborator

jlurien commented Jan 24, 2023

@eric-murray The proposal looks good to me. Not sure if additional_info has to be required or there may be scenarios without CGNAT where it is enough to provide only the public_address . Also regarding format for Ipv4Addr, are there use cases to allow masks for the public and private addresses, or a single IP should be provided in order to identify UE?

@eric-murray
Copy link
Collaborator Author

Thanks @jlurien . On the points you raise:

  • Once upon a time we did actually allocate public IP addresses directly to the UE, but I'm not aware of any mobile operator that still does that. But it remains a possibility, of course, albeit an unlikely one. Private networks also need to be considered, where private addresses will be used between the UE and local application servers with no CGNAT.

    My proposal would be that where the source IP allocated to the UE is the same as that seen by the application server, then that address should be specified as both the public_address and additional_info->private_address. This would be the case whether the address itself was public or private (e.g. for private networks). Of course, for this scenario, the terms "private" and "public" might be confusing, but alternatives such as "local" and "remote" risk being equally confusing for other scenarios.

  • The IP address(es) used to identify the UE should indeed be single addresses. I don't see any scenario where it would make sense to specify a subnet with a mask (other than /32 of course). I can introduce a new SingleIpv4Addr schema that only accepts single addresses with no mask. At some point, such schema should be moved to a separate common library.

@jlurien
Copy link
Collaborator

jlurien commented Jan 24, 2023

If the private_address is the IP address seen by the device and may be a public address in some cases, a name such as device_address or local_address would make sense, but if a private address is by far the common case, we can keep it that way, with an appropriate description.

I think also that defining a SingleIpv4Addr is convenient.

Thanks!

@sfnuser
Copy link
Collaborator

sfnuser commented Jan 25, 2023

  • Multiple inconstant properties specified (supplied identifiers identify different UEs)
  • No UE can be identified from the specified identifiers (e.g. MSISDN is not a customer of the API provider)

@eric-murray Are these errors translated from Network error response? My assumption is that it may not be practical for the operator to provision UE details to the QoD service to do the validation.

Regarding the uePorts field removal, I believe it would still be useful to have this field on the private networks use case as discussed below. We still intend to create a Flow Description for NEF using the uePorts field. Thoughts please!

My proposal would be that where the source IP allocated to the UE is the same as that seen by the application server, then that address should be specified as both the public_address and additional_info->private_address. This would be the case whether the address itself was public or private (e.g. for private networks). Of course, for this scenario, the terms "private" and "public" might be confusing, but alternatives such as "local" and "remote" risk being equally confusing for other scenarios.

@jlurien
Copy link
Collaborator

jlurien commented Jan 25, 2023

@sfnuser If the current uePorts are still valid for a use case other than UE identification, we should delimit that separately and adjust documentation accordingly. In the current version is not well distinguished. Maybe we can further elaborate on it on a separate issue about Flow description.

@eric-murray
Copy link
Collaborator Author

@sfnuser

Are these errors translated from Network error response? My assumption is that it may not be practical for the operator to provision UE details to the QoD service to do the validation.

I think what you are asking here is that, if the only southbound network element interface available to the QoD API is the T8 AsSessionWithQoS, then how can the MSISDN and/or External ID identifiers be validated for consistency with any IP address that is specified? In that scenario, indeed MSISDN and External ID cannot be used to identify the UE, as the AsSessionWithQoS interface does not accept these parameters. So I guess we need an "Specified identifier not supported" error message for implementations that do not support UE identification by MSISDN or External ID.

As we allow multiple identifiers to be specified by the client, my view is that the API should validate them all for consistency rather than just pick the one that is most convenient to use southbound and ignore the rest. The alternative would be to limit ueId to be a single identifier, which is a reasonable approach but does rule out setting up simultaneous IPv4 and IPv6 flows for dual-stack UEs.

Regarding the uePorts field removal, I believe it would still be useful to have this field on the private networks use case as discussed below. We still intend to create a Flow Description for NEF using the uePorts field. Thoughts please!

The scenario here is not clear to me. Is there a scenario in which, for a given application server target (say 10..0.0.1:443), then some active UE flows to that target should be prioritised (e.g. 10.100.0.1:50000) but other active flows (e.g. 10.100.0.1:50001) should not? What is that scenario?

My expectation was that a UE port wildcard would be used to set-up the flow (10.100.0.1:*), even the UE has been identified by IP address and (a single) public port. If there is a scenario where UE private port range needs to be restricted for the QoS flows, then uePorts can be kept, though maybe re-named ue_private_ports.

@hdamker
Copy link
Collaborator

hdamker commented Jan 25, 2023

@eric-murray Thanks for the detailed and good discussion.

Some thoughts - knowing that it will get difficult to cover all cases in a way which is both easy to understand and easy to use:

  • There are more cases then just CGNAT for IPv4:

    • Network with internally IPv6 only - without private IPv4 addresses for the devices. E.g. with our standard APN IPv4 is suppoted via DNS64+NAT64, for literal IPv4 addresses the client need to support 464XLAT (e.g. the case forAndroid, Apple is requiring IPv6 support for applications within the Appstore since 2015). We started to set an IPv6 only APN as standard within 2020 and doing so now with the majority of new devices.
    • Beside the standard IPv6 only APN we are still offering dual stack APN with CGNAT (e.g. for devices which are not supporting 464XLAT and would break applications with literal IPv4 addresses)
    • Special/legacy APNs without CGNAT - already mentioned above, e.g. in private networks or for special cases
  • Not supported identifiers should be ignored as long as supported identifiers are valid. Only if the request is coming without any of the supported ones, the error "Specified identifier(s) not supported" should be returned

  • Responses in case of correctly formatted but invalid identifiers might need to be neutral, to avoid side information

  • To get the inputif the resulting QoS session should include IPv4, IPv6 or both flows we can use the given application server address(es). That would allow us to not require IPv4/v6 addresses as UEId if e.g. MSISDN or external ID is supported and sufficient. Even the combination of IPv6addr as UEId and IPv4addr as ASId could make sense then ... the UEId IPv6addr will just identify the device, while the the IPv4addr for ASId will indicate that IPv4 flows should be prioritized.

@sfnuser
Copy link
Collaborator

sfnuser commented Jan 25, 2023

@eric-murray Thanks for the clarifications.

my view is that the API should validate them all for consistency

By validate, I assume we mean format checking only - correct? For e.g. if the UE passes v4 & v6 addr, do we expect the QoD service to validate the v4 & v6 addresses matches for a UE? The NFs have to do this validation anyway and moving this forward to QoD service also means provisioning the UE data again for QoD. Not sure if such validation is required at QoD level for ueId. I agree that asId shall be validated at QoD service because the App Server has to register with the QoD service as per the clientCredentials authorization flow.

Also, if a UE provides v4 & v6 address for CreateSession to a setup with T8 API (NEF) on southbound (that expects v4 or v6 address - one of them only), I am not sure how the QoD service would validate both the ids in this case. I agree with @hdamker's point below.

Not supported identifiers should be ignored as long as supported identifiers are valid

@eric-murray @jlurien Yes, in the current versions, it is not mentioned that uePorts are to be used as part of UE identification. If the new proposed schema of public_port is to be used, uePorts need not be removed. For e.g. uePorts and asPorts can be used to define a FlowDescription (for e.g. SDPs as defined in 29.214 Appendix B2 where different ports of the same UE are used for different flows) parameter required for the T8 API on southbound. I agree on renaming the uePorts to some other name if we feel public_port in the new schema will cause confusion.

@hdamker Thanks for the inputs. It's nice to know about the scenarios you have added.

Not supported identifiers should be ignored as long as supported identifiers are valid. Only if the request is coming without any of the supported ones, the error "Specified identifier(s) not supported" should be returned

Responses in case of correctly formatted but invalid identifiers might need to be neutral, to avoid side information

Agreed.

@eric-murray
Copy link
Collaborator Author

Thanks @sfnuser

By validate, I assume we mean format checking only - correct?

No. I meant that, where the API client supplies multiple UE identifiers that identify different UEs, then I would expect this to be flagged to the client as an error. However, this is implementation dependent behaviour - there is no requirement that all implementations of the API behave identically, and an implementation can choose to ignore identifiers that it cannot validate. Rather, I'm just identifying the need for a "Multiple inconstant properties specified" error message to be available for those implementations that need it. The alternative is to mandate that only a single UE identifier be supplied.

As a side note, Vodafone would not use the NEF itself to validate these parameters and, more generally, our policy is not to throw unverified parameters supplied by 3rd parties at our southbound network elements and rely on them to detect any errors. The teams managing those network elements don't like that at all.

For e.g. uePorts and asPorts can be used to define a FlowDescription

So the purpose of this proposal is to solve the issue of identifying a UE from a private IPv4 address. Requirements for defining flows is a separate issue, so uePorts can remain until all the requirements are identified. As @hdamker points out, there are a whole bunch of IPv4 / IPv6 interworking scenarios to be considered. So I will not even propose to rename uePorts to ue_private_ports as it may be this field is only required for scenarios involving IPv6 where "private" ports are not really a thing.

So my proposal to resolve the IPv4 private address ambiguity remains as above, but uePorts will remain.

@sfnuser
Copy link
Collaborator

sfnuser commented Jan 26, 2023

Thanks @eric-murray for the clarifications.

the need for a "Multiple inconstant properties specified" error message to be available for those implementations that need it

I agree.

On a side note, when multiple UE Ids are passed to QoD service and if only one of the id is used southbound, can we use the successful response body SessionInfo -> CreateSession -> UeId field to indicate which UE id is really used to create session? If we choose to ignore unsupported ids and use only the supported one, this may be a way to indicate which id is really used with the network. Do you see any issues?

So my proposal to resolve the IPv4 private address ambiguity remains as above, but uePorts will remain.

I agree. Thanks.

@hdamker
Copy link
Collaborator

hdamker commented Feb 23, 2023

Should I wait for the discussions on terminology to be finalised?

I wouldn't wait, the changes will be mainly a search and replace through the YAML and documentation, but we might wait with that until there is also a discussion in Commonalities done (and there is also snake_case vs camelCase).

Is there a deadline for those votes?

We can discuss that tomorrow. Maybe we can also ask to do it directly. If not waiting for in total 7 days might be right.

@jlurien
Copy link
Collaborator

jlurien commented Feb 24, 2023

I wouldn't wait too much either. Discussions around commonalities are never ending. I think it's better to progress on functionality and if guidelines change, adapt our latest version to them. Changing formats is no-brain.

@eric-murray
Copy link
Collaborator Author

PR #123 created

@sfnuser
Copy link
Collaborator

sfnuser commented Feb 28, 2023

Ah! I made comments on the PR based on earlier decisions. I could not make it to the last week's call and I see there are updates. Looks good.

I also assume that we are not considering scenarios mentioned by @hdamker (involving combination of ipv4 & v6 addresses here) at this point?

@eric-murray
Copy link
Collaborator Author

I also assume that we are not considering scenarios mentioned by @hdamker (involving combination of ipv4 & v6 addresses here) at this point?

This issue and associated PR are not intended to cover combined IPv4/IPv6 scenarios. I would suggest that anyone who wants a specific scenario to be considered should open an issue if that scenario is not covered by the current API definition.

@eric-murray
Copy link
Collaborator Author

Given the discussion paper presented in PR #127 and some additional research on my part, I'd like to return to my original proposal in an above comment, but modifying it to make the logical constraints on allowed parameter combinations much clearer and intuitive.

So object UeId would still be modified as follows to allow a new custom object to be used to identify a UE by IPv4 address:

UeId:
  type: object
  minProperties: 1
  properties:
    network_access_identifier:
      $ref: "#/components/schemas/ExternalId"
    msisdn:
      $ref: "#/components/schemas/MSISDN"
    ipv4_address:
      $ref: "#/components/schemas/UeIpv4Addr"
    ipv6_address:
      $ref: "#/components/schemas/Ipv6Addr"
  description: Device identifier

where the custom object UeIpv4Addr is defined as:

UeIpv4Addr:
  type: object
  properties:
    public_address:
      $ref: "#/components/schemas/SingleIpv4Addr"
    private_address:
      $ref: "#/components/schemas/SingleIpv4Addr"
    public_port:
      $ref: "#/components/schemas/Port"
  oneOf:
    - required: [public_address, private_address]
    - required: [public_address, public_port]

and IPv4 addresses are restricted to a single address using the new object SingleIpv4Addr:

SingleIpv4Addr:
  type: string
  format: ipv4
  description: A single IPv4 address, following the 3GPP TS 29.571 pattern
  example: "84.125.93.10"
  pattern: '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$'

Using the terminology in PR #127, UeIpv4Addr would become:

UeIpv4Addr:
  type: object
  properties:
    observed_address:
      $ref: "#/components/schemas/SingleIpv4Addr"
    local_address:
      $ref: "#/components/schemas/SingleIpv4Addr"
    observed_port:
      $ref: "#/components/schemas/Port"
  oneOf:
    - required: [observed_address, local_address]
    - required: [observed_address, observed_port]

I have no preference as to whether the terminology public/private or observed/local is used.

Specifying multiple required parameter options using the oneOf construct is entirely valid OAS syntax. To me, it is very clear what required parameter combination options are available when reading this. However, I'm sure the objection will be that current code generators will not like this construct at all. I would suggest developers spend more time enhancing the functionality of code generators rather than complaining about them.

@patrice-conil
Copy link
Collaborator

patrice-conil commented Mar 10, 2023

@eric-murray,
IMHO giving a spec that produces code that compiles is good way to produce a friendly API ... That's why I complain when it isn't the case. ;-)

Maybe you can use a construct like this

   UeIpv4Addr:
      type: object
      properties:
        observed_address:
          $ref: "#/components/schemas/SingleIpv4Addr"
        local_address:
          $ref: "#/components/schemas/SingleIpv4Addr"
        observed_port:
          $ref: "#/components/schemas/Port"
      required:
        - observed_address
        - oneOf: 
          - observed_port
          - local_address 

Because this one is more openapi-generator friendly and seems also to be readable
What do you think about ?

@eric-murray
Copy link
Collaborator Author

@patrice-conil
Yes, I agree that approach is better. I still regard the private/public or local/observed discussion as open however!.

@jlurien
Copy link
Collaborator

jlurien commented Mar 10, 2023

@eric-murray, IMHO giving a spec that produces code that compiles is good way to produce a friendly API ... That's why I complain when it isn't the case. ;-)

Maybe you can use a construct like this

   UeIpv4Addr:
      type: object
      properties:
        observed_address:
          $ref: "#/components/schemas/SingleIpv4Addr"
        local_address:
          $ref: "#/components/schemas/SingleIpv4Addr"
        observed_port:
          $ref: "#/components/schemas/Port"
      required:
        - observed_address
        - oneOf: 
          - observed_port
          - local_address 

Because this one is more openapi-generator friendly and seems also to be readable What do you think about ?

I think that this schema is not compliant with the openapi spec. required is specified as an array of unique strings, intended to list property names, and oneOf is an array of Schemas (or references to schemas):

  Schema:
    type: object
    properties:
...
      required:
        type: array
        items:
          type: string
        minItems: 1
        uniqueItems: true
...
      oneOf:
        type: array
        items:
          oneOf:
            - $ref: '#/definitions/Schema'
            - $ref: '#/definitions/Reference'

I think that the original proposal by @eric-murray is compliant to the spec, but some generator may have problems with it. It may be more supported by generators, but more redundant, to reference both alternative schemas:

UeIpv4Addr:
  oneOf:
    - $ref: '#/components/schemas/AddressPort'
    - $ref: '#/components/schemas/BothAddresses'
AddressPort:
  - type: object
    required:
      - observed_address
      - observed_port
    properties:
      observed_address:
        $ref: '#/components/schemas/SingleIpv4Addr'
      observed_port:
        $ref: '#/components/schemas/Port'
BothAddresses:
  - type: object
    required:
      - observed_address
      - local_address
    properties:
      observed_address:
        $ref: '#/components/schemas/SingleIpv4Addr'
      local_address:
        $ref: '#/components/schemas/SingleIpv4Addr'

But this may depend on the generator used, some may even work with the non-compliant version, but we should avoid it.

@patrice-conil
Copy link
Collaborator

@eric-murray,
Thanks for your agreement.
Personally, I prefer public/private...because that's how addresses are named in the IP world itself.
But I will accept another denomination if a consensus emerges.
Maybe a vote could help to choose ? it seems to be in tune with the times.

@patrice-conil
Copy link
Collaborator

@jlurien,
You're right ... I was cheated by the new editor which is too permissive... and the embeded generator which accepts the spec.

@eric-murray
Copy link
Collaborator Author

I posted details of how the scenario this issue was intended to address (that of the device itself calling the QoD API) would actually work in a comment in PR #127. Please have a look if you did not understand the full context of this specific issue.

@jlurien
Thanks for the alternative proposal. My feeling is that your proposal obscures the requirements on the API caller a bit more than my proposal as they then have to go and look at the details of the additional objects to get that. But if more code generators are happier with this construct, then that would be a reason in favour of it. Maybe we should let the code generators also vote!

But the important point is that both proposals enforce the valid parameter options on the API caller, which is not achieved by the proposal in PR #127, which is why I am not in favour of that proposal.

@emil-cheung
Copy link
Collaborator

UE IP address and ports in QoD.pdf

I attach a revised discussion paper for this issue.
The major update from the version I presented is one more scenario about how developers will call QoD API, as Vodafone suggested, Device App directly calls QoD API (p7).

In this scenario, we generalize how Device App can obtain observed UE IP address and observed UE port(s), i.e., from an Application Server which may be DNS or Traffic Application Server.

@emil-cheung
Copy link
Collaborator

emil-cheung commented Mar 16, 2023

Ericsson's proposal:

  1. Modify 'UeId' datatype:
    UeId:
      type: object
      required:
        - observedIpAddr
      properties:
        externalId:
          $ref: "#/components/schemas/ExternalId"
        msisdn:
          $ref: "#/components/schemas/MSISDN"
        assignedIpAddr:
          oneOf:
            - $ref: "#/components/schemas/Ipv4Addr"
            - $ref: "#/components/schemas/Ipv6Addr"
        observedIpAddr:
          oneOf:
            - $ref: "#/components/schemas/Ipv4Addr"
            - $ref: "#/components/schemas/Ipv6Addr"
      description: User equipment identifier
  1. Introduce a new 'UePorts' datatype:
    UePorts:
      type: object
      required:
        - observedPorts
      properties:
        localPorts:
          $ref: "#/components/schemas/PortsSpec"
        observedPorts:
          $ref: "#/components/schemas/PortsSpec"

@eric-murray
Copy link
Collaborator Author

@emil-cheung
Can you clarify what information you think needs to be in the QoD API call for each of the 3 scenarios?

From your presentation, it looks like you believe that the API caller needs to provide all of the private / public IP addresses and ports involved, which is just not necessary. But from your proposed definitions above, only observedIpAddr and observedPorts are mandatory, but mandatory for all scenarios which again is unnecessary.

The other proposals above attempt to strike a balance between allowing the API caller flexibility in what parameters they provide, whilst still placing some constraints on parameter combinations to try and avoid the API caller providing insufficient parameters.

Just to document some comments I made in the last meeting about the IPv4 CGNAT case:

  • Identifying the device and specifying the flow rules are separate issues
  • To identify the device:
    • The private source IP address is only useful in combination with the public IP address
    • The public source ports are only useful in combination with the public source IP address, and specifying only a single port is sufficient. Specifying multiple public source ports is unnecessary.
    • The private source ports are not useful at all
    • If the device is identified by one of the other identifiers (msisdn, externalId) then specifying public source IP addresses and ports is unnecessary.
  • To identify the flow rules:
    • The public source IP address and public source ports are not useful at all
    • The private source ports are generally not required, as using wildcards for these in the flow rules gives exactly the same effect.
      • The one exception to this I can think of would be when the device is acting as a router, in which case multiple flows might be using the same application server address / port combination and it is possible that they require different QoS profiles. But for that scenario, I don't see how the private source ports involved can be determined, so I would exclude this scenario from any analysis.

Commenting on the presentation:

  • The technique I outlined in this comment to allow a device to determine its public IPv4 address via DNS is available now, but does not allow the device to determine its public source port as seen by the application server. But, as mentioned above, public source port information is not necessary if the private source IP address is known.
  • Whilst the target application server itself could in theory provide the device public source IP address back to the device, that would appear to be unnecessary development given that the DNS technique exists now. And if the application server is anyway involved in the QoD use case, it may as well make the QoD API call itself. Providing public source port information back to the device is not useful.

@emil-cheung
Copy link
Collaborator

emil-cheung commented Mar 20, 2023

@emil-cheung Can you clarify what information you think needs to be in the QoD API call for each of the 3 scenarios?

From your presentation, it looks like you believe that the API caller needs to provide all of the private / public IP addresses and ports involved, which is just not necessary. But from your proposed definitions above, only observedIpAddr and observedPorts are mandatory, but mandatory for all scenarios which again is unnecessary.

The other proposals above attempt to strike a balance between allowing the API caller flexibility in what parameters they provide, whilst still placing some constraints on parameter combinations to try and avoid the API caller providing insufficient parameters.

Just to document some comments I made in the last meeting about the IPv4 CGNAT case:

  • Identifying the device and specifying the flow rules are separate issues

  • To identify the device:

    • The private source IP address is only useful in combination with the public IP address
    • The public source ports are only useful in combination with the public source IP address, and specifying only a single port is sufficient. Specifying multiple public source ports is unnecessary.
    • The private source ports are not useful at all
    • If the device is identified by one of the other identifiers (msisdn, externalId) then specifying public source IP addresses and ports is unnecessary.
  • To identify the flow rules:

    • The public source IP address and public source ports are not useful at all

    • The private source ports are generally not required, as using wildcards for these in the flow rules gives exactly the same effect.

      • The one exception to this I can think of would be when the device is acting as a router, in which case multiple flows might be using the same application server address / port combination and it is possible that they require different QoS profiles. But for that scenario, I don't see how the private source ports involved can be determined, so I would exclude this scenario from any analysis.

Commenting on the presentation:

  • The technique I outlined in this comment to allow a device to determine its public IPv4 address via DNS is available now, but does not allow the device to determine its public source port as seen by the application server. But, as mentioned above, public source port information is not necessary if the private source IP address is known.
  • Whilst the target application server itself could in theory provide the device public source IP address back to the device, that would appear to be unnecessary development given that the DNS technique exists now. And if the application server is anyway involved in the QoD use case, it may as well make the QoD API call itself. Providing public source port information back to the device is not useful.

UE IP address and ports in QoD.PA3.pdf

@eric-murray , please check p11-p13 in PA3 of my discussion paper, for the QoD request examples.
For each scenario, I list the following 3 sub-scenarios:

  • IPv4 with NAT
  • IPv6 without NAT
  • NAT64
    @hdamker , you may look into the NAT64 aspect.

Technically, we understand the combinations of 'minimum' attributes for various scenarios, but we would like to argue the necessity for developers.

First of all, when a developer 'observes' a device connection from an Application Server, he always gets observed UE ports together with observed UE IP address. Always putting observed UE ports together with observed UE IP address in QoD request requires 'no additional cost'.

Secondly, these combinations of 'minimum' attributes require developers to have knowledge about CSP network deployments (NAT, no NAT, NAT64) and telecom concepts (PDU session identification, CGNAT).

Last, but not least, CAMARA layer shall provide 'intelligence' to adapt to different CSP network deployments (CAMARA also supports the aggregator role) and hide unnecessary telecom concepts.

Again, the essence of Ericsson proposal is to let developers provide what they get (WHAT), and let CAMARA layer figure out how to use (HOW).

@hdamker
Copy link
Collaborator

hdamker commented Apr 14, 2023

@eric-murray #129 is finally merged, so the way is free for the next PRs. Would it be able for you to create your PR before the next call on April 21st (to follow the proposed timeline in #136)?

@eric-murray
Copy link
Collaborator Author

eric-murray commented Apr 18, 2023

@emil-cheung
I couldn't attend the last QoD meeting, so missed any discussion of your updated proposal. However, I still think you are missing the point for Scenario 3 (Direct device QoD boost call), which is that the device does not need to know its public ports in order to identify both itself and the flow.

The public ports would only be known to the actual application server that the QoS flow would be created for, and "customising" the application server to provide a mechanism to communicate this information to the device would appear to be a pointless overhead given that the information is not required.

Given that the reason for including this scenario was to allow a device to use the QoD API even if the application server knows nothing about it or CAMARA APIs, including device public ports in the API call rather defeats this objective. The device only needs to know any public IP address is it currently using in order to identify the IP domain, and DNS can provide this information.

For the three "sub-scenarios" you consider (IPv4-NAT, IPv6 - No NAT, NAT 64), then my proposal above (modified to the updated terminology) would look as follows. Terminology can be changed, of course. Use of the publicPort field within "ipv4Address" is only required when an application server calls the QoD API (Scenarios 1 and 2), and is used instead of privateAddress. I can give examples for those scenarios if required.

IPv4-NAT

{
  ...
  "device": {
    "ipv4Address": {
      "publicAddress": "152.190.161.1",
      "privateAddress": "100.64.1.12"
    }
  },
  ...
}

IPv6 - No NAT

{
  ...
  "device": {
    "ipv6Address": "2001:db8:85a3:8d3:1319:8a2e:370:7344"
  },
  ...
}

NAT64

{
  ...
  "device": {
    "ipv4Address": {
      "publicAddress": "152.190.161.1"
    },
    "ipv6Address": "2001:db8:85a3:8d3:1319:8a2e:370:7344"
  },
  ...
}

Note that, if this last scenario is a valid scenario, then both the privateAddress and publicPort fields of ipv4Address would need to be optional.

@eric-murray
Copy link
Collaborator Author

@hdamker Yes, I will create a PR before Friday based on the current WIP API definition

@eric-murray
Copy link
Collaborator Author

@hdamker
Following up on my last comment in my reply to @emil-cheung, for the NAT 64 scenario when the QoD API call is made by the device, is the IPv6 address of the device (i.e. the "assigned" address) sufficient to identify the device for the scenarios of interest to DT, or can it be ambiguous in the same way that the assigned address can be ambiguous for the NAT 44 scenario?

If the IPv6 address alone is sufficient to identify the device, then the device would not need to provide its public (observed) IPv4 address in order to identify itself.

@hdamker
Copy link
Collaborator

hdamker commented Apr 20, 2023

@eric-murray

If the IPv6 address alone is sufficient to identify the device, then the device would not need to provide its public (observed) IPv4 address in order to identify itself.

IPv6 address alone is sufficient for us (as same prefix is also used for the public/observed IPv6 address).

@emil-cheung
Copy link
Collaborator

@emil-cheung I couldn't attend the last QoD meeting, so missed any discussion of your updated proposal. However, I still think you are missing the point for Scenario 3 (Direct device QoD boost call), which is that the device does not need to know its public ports in order to identify both itself and the flow.

The public ports would only be known to the actual application server that the QoS flow would be created for, and "customising" the application server to provide a mechanism to communicate this information to the device would appear to be a pointless overhead given that the information is not required.

Given that the reason for including this scenario was to allow a device to use the QoD API even if the application server knows nothing about it or CAMARA APIs, including device public ports in the API call rather defeats this objective. The device only needs to know any public IP address is it currently using in order to identify the IP domain, and DNS can provide this information.

For the three "sub-scenarios" you consider (IPv4-NAT, IPv6 - No NAT, NAT 64), then my proposal above (modified to the updated terminology) would look as follows. Terminology can be changed, of course. Use of the publicPort field within "ipv4Address" is only required when an application server calls the QoD API (Scenarios 1 and 2), and is used instead of privateAddress. I can give examples for those scenarios if required.

IPv4-NAT

{
  ...
  "device": {
    "ipv4Address": {
      "publicAddress": "152.190.161.1",
      "privateAddress": "100.64.1.12"
    }
  },
  ...
}

IPv6 - No NAT

{
  ...
  "device": {
    "ipv6Address": "2001:db8:85a3:8d3:1319:8a2e:370:7344"
  },
  ...
}

NAT64

{
  ...
  "device": {
    "ipv4Address": {
      "publicAddress": "152.190.161.1"
    },
    "ipv6Address": "2001:db8:85a3:8d3:1319:8a2e:370:7344"
  },
  ...
}

Note that, if this last scenario is a valid scenario, then both the privateAddress and publicPort fields of ipv4Address would need to be optional.

Eric,
A device App may not get the local IP address (e.g., an App running in web browser). In this case, observed IP + observed port are required, which means DNS information is not enough.

In NAT64 case, if the device App cannot get the local IP address (which is IPv6 address), it needs to use the observed IP + observed port (which is IPv4 address).

@eric-murray
Copy link
Collaborator Author

I created PR #139 to address this issue. Please have a look.

@emil-cheung

A device App may not get the local IP address (e.g., an App running in web browser)

This issue was created to address the scenario where it was desired to identify the device by its private (allocated) IPv4 address. If it is not possible to get this information, then this issue does not apply. The API has always supported and will continue to support identifying devices by public IPv4 address and port, along with other methods of identifying the device.

In NAT64 case, if the device App cannot get the local IP address (which is IPv6 address), it needs to use the observed IP + observed port (which is IPv4 address).

Again, this issue does not affect NAT64 scenarios. For those, the device can either be identified by its IPv6 address alone or, if this is not known, by its public (observed) IPv4 address and port. Both these methods are supported and will continue to be supported.

@eric-murray
Copy link
Collaborator Author

@hdamker
On updated naming, two votes are required:

Vote 1: DeviceIpv4Addr object properties

Option 1 : publicAddress, privateAddress & publicPort
Option 2 : observedAddress, allocatedAddress & observedPort

Vote 2: Rename of devicePorts property of CreateSession object

Option 1 : deviceAllocatedPorts
Option 2 : deviceLocalPorts
Option 3 : deviceSourcePorts

If anyone has additional options they would like considered, please add a comment below.

@hdamker
Copy link
Collaborator

hdamker commented Apr 27, 2023

@eric-murray
Votes are created and open until next Thursday, May 4th, 12:00 UTC:

  1. Vote: DeviceIpv4Addr object properties (from PR #139)
  2. Vote: Rename of devicePorts property of CreateSession object

Hope that will give you enough time to update the PR before our next call if needed.

P.S.: I've reduced the options for vote 2 to the ones listed in #139 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants