Data ports and maximum number of bearers

Bjørn Mork bjorn at mork.no
Tue Sep 20 09:16:34 UTC 2016


Carlo Lobrano <c.lobrano at gmail.com> writes:

> Initially I'd like to investigate this topic without considering the
> protocol (AT, MBIM, QMI), and only the modem's capabilities, although this
> note from the above mentioned discussion is really appealing
>
> MBIM modems can multiplex IP sessions over a single data port.
>
>
> ​and as Dan said, QMI should not support this with a single data port.​

QMI should already work fine I think.  The driver creates a cdc-wdm
device and a NET port per QMI function, and modems with more than one
function will therefore have more than one data port available.

The driver ignores the non-functional third QMI port on the Sierra
modems with this problem, so I believe there is no need for MM or
anything else to be aware of that issue.

> Also this note caught my attention
>
> There's an issue here; the port needs to be a NET port, because that
>> is what the Bearer should export in the interface. This is, if you
>> have 2 bearers, they should both expose "wwan0", and not
>> "/dev/cdc-wdm...". NetworkManager needs to know which is the NET port
>> where the IP config
>> is to be applied.
>
>
> does this mean that the required changes will touch other actors (like
> NetworkManager and/or the driver)?

I don't think so.  NetworkManager only needs the NET port and address
info.  The driver already supports creating additional NET ports
representing the multiplexed MBIM IP sessions, mapping them to VLAN
interfaces on top of the single default port.  The driver API is
documented here:
https://www.kernel.org/doc/Documentation/networking/cdc_mbim.txt

So you can set up multiple MBIM IP sessions manually using the "ip" and
"mbimcli" tools today.  What's missing is the part that creates and
deletes the NET ports as needed, and mapping these to bearers and MBIM
session IDs in ModemManager.

I guess an example of how to create multiple sessions can help explain
how the existing driver and libmbim support works:


1) this modem supports up to 8 sessions:


     # mbimcli -p -d /dev/cdc-wdm0  --query-device-caps 
[/dev/cdc-wdm0] Device capabilities retrieved:
              Device type: 'remote'
           Cellular class: 'gsm'
              Voice class: 'no-voice'
                Sim class: 'removable'
               Data class: 'umts, hsdpa, hsupa, lte'
                 SMS caps: 'pdu-receive, pdu-send'
                Ctrl caps: 'reg-manual'
             Max sessions: '8'
        Custom data class: 'unknown'
                Device ID: xxx
            Firmware info: 'SWI9X30C_02.20.03.00'
            Hardware info: 'EM7455'


2) the NET interface created by the driver is named wwan0.  We create
   three new interfaces on top of it, representing MBIM session IDs 0,1
   and 2:


    # ip link add link wwan0 name wwan0.0 type vlan id 4094 
    # ip link add link wwan0 name wwan0.1 type vlan id 1
    # ip link add link wwan0 name wwan0.2 type vlan id 2

3) and bring up the main interface and make sure we're attached to the network
 
    # ip link set wwan0 up

    # mbimcli -p -d /dev/cdc-wdm0 --attach-packet-service
[/dev/cdc-wdm0] Successfully attached to packet service

[/dev/cdc-wdm0] Packet service status:
                 Network error: 'unknown'
          Packet service state: 'attached'
        Available data classes: 'lte'
                  Uplink speed: '50000000 bps'
                Downlink speed: '300000000 bps'


4) then we connect three different sessions to different APNs, one IPv6
  only, one NATed IPv4 and one IPv4 with a public IP address:


   # mbimcli -p -d /dev/cdc-wdm0 --connect=session-id=0,apn=ims
[/dev/cdc-wdm0] Successfully connected

[/dev/cdc-wdm0] Connection status:
              Session ID: '0'
        Activation state: 'activated'
        Voice call state: 'none'
                 IP type: 'ipv6'
            Context type: 'internet'
           Network error: 'unknown'

[/dev/cdc-wdm0] IPv4 configuration available: 'none'

[/dev/cdc-wdm0] IPv6 configuration available: 'address, gateway, mtu'
     IP [0]: '2a02:2121:105:fd6d:8887:f6a8:c14b:1dc2/64'
    Gateway: '2a02:2121:105:fd6d:31df:2343:a046:245'
        MTU: '1500'

   # mbimcli -p -d /dev/cdc-wdm0 --connect=session-id=1,apn=telenor.smart
[/dev/cdc-wdm0] Successfully connected

[/dev/cdc-wdm0] Connection status:
              Session ID: '1'
        Activation state: 'activated'
        Voice call state: 'none'
                 IP type: 'ipv4'
            Context type: 'internet'
           Network error: 'unknown'

[/dev/cdc-wdm0] IPv4 configuration available: 'address, gateway, dns, mtu'
     IP [0]: '10.130.163.117/30'
    Gateway: '10.130.163.118'
    DNS [0]: '193.213.112.4'
    DNS [1]: '130.67.15.198'
        MTU: '1500'

[/dev/cdc-wdm0] IPv6 configuration available: 'none'

   # mbimcli -p -d /dev/cdc-wdm0 --connect=session-id=2,apn=telenor
[/dev/cdc-wdm0] Successfully connected

[/dev/cdc-wdm0] Connection status:
              Session ID: '2'
        Activation state: 'activated'
        Voice call state: 'none'
                 IP type: 'ipv4'
            Context type: 'internet'
           Network error: 'unknown'

[/dev/cdc-wdm0] IPv4 configuration available: 'address, gateway, dns, mtu'
     IP [0]: '46.156.97.6/30'
    Gateway: '46.156.97.5'
    DNS [0]: '193.213.112.4'
    DNS [1]: '130.67.15.198'
        MTU: '1500'

[/dev/cdc-wdm0] IPv6 configuration available: 'none'


5) and configure the addressing (except IPv6 addresses which are
  autoconfigured using SLAAC as long as the interface is up when
  connecting):
  
  # ip addr add 10.130.163.117/32 dev wwan0.1
  # ip addr add 46.156.97.6/32 dev wwan0.2


  The MBIM related NET ports now look like this:

  # ip addr show|tail -22
10: wwan0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 9e:81:5f:2f:36:bf brd ff:ff:ff:ff:ff:ff
    inet6 fe80::9c81:5fff:fe2f:36bf/64 scope link 
       valid_lft forever preferred_lft forever
11: wwan0.0 at wwan0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9e:81:5f:2f:36:bf brd ff:ff:ff:ff:ff:ff
    inet6 2a02:2121:105:fd6d:9c81:5fff:fe2f:36bf/64 scope global mngtmpaddr dynamic 
       valid_lft forever preferred_lft forever
    inet6 fe80::9c81:5fff:fe2f:36bf/64 scope link 
       valid_lft forever preferred_lft forever
12: wwan0.1 at wwan0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9e:81:5f:2f:36:bf brd ff:ff:ff:ff:ff:ff
    inet 10.130.163.117/32 scope global wwan0.1
       valid_lft forever preferred_lft forever
    inet6 fe80::9c81:5fff:fe2f:36bf/64 scope link 
       valid_lft forever preferred_lft forever
13: wwan0.2 at wwan0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9e:81:5f:2f:36:bf brd ff:ff:ff:ff:ff:ff
    inet 46.156.97.6/32 scope global wwan0.2
       valid_lft forever preferred_lft forever
    inet6 fe80::9c81:5fff:fe2f:36bf/64 scope link 
       valid_lft forever preferred_lft forever




6) I don't know how to best demonstrate that this works, but using a
  "get public IP" service is one way:

   $ host api.ipify.org
api.ipify.org is an alias for api.ipify.org.herokudns.com.
api.ipify.org.herokudns.com has address 54.221.194.87

   # ip route add 54.221.194.87 dev wwan0.1
   $ curl 'https://api.ipify.org?format=json'
{"ip":"2.150.42.73"}

   # ip route del 54.221.194.87 dev wwan0.1
   # ip route add 54.221.194.87 dev wwan0.2
   $ curl 'https://api.ipify.org?format=json'
{"ip":"46.156.97.6"}r


I can unfortunately not demonstrate this for session 0, since I have no
idea which addresses are reachable there.  It's not the Internet, but an
IMS VPN (as you might have guessed from the APN). As you can see above,
it doesn't even have name servers.  But I currently have a shortage of
valid APNs for testing :-(

Note that it wasn't strictly necessary to create a new NET interface for
session 0.  We could have used the top level interface instead, as we
currently do in ModemManager. But creating the VLAN is more consistent,
and allows you to set the MTU independently for all sessions.



Bjørn


More information about the ModemManager-devel mailing list