Bug #4434

sgsnemu: Fix wrong assumption always Interface Identifier == IPv6 public prefix

Added by pespin about 1 month ago.

Target version:
Start date:
Due date:
% Done:


Spec Reference:


osmo-ggsn currently (20539f02713fc5a1f8f2248555d4a199e57cda98) uses same 64 bits value in the Interface Identifier (IPv6 GTP EUA sent during Create Pdp Ctx Response) as well as later for the IPv6 prefix (during Router Advertisement).
That's really an implementation details and it doesn't necessarily need to be the case as per spec (they can have totally different values). For instance, ergw uses a constant Interface identifier of ::1 for all UEs.

sgsnemu currently expects the Interface Identifier to be the same as the IPv6 public prefix later received, which means it won't work properly when used against ergw (on IPv6).

Probably this diff for osmo-ggsn allows quickly running into a similar scenario in sgsnemu (receiving different values):

diff --git a/ggsn/icmpv6.c b/ggsn/icmpv6.c
index 12119b8..240c89c 100644
--- a/ggsn/icmpv6.c
+++ b/ggsn/icmpv6.c
@@ -142,6 +142,7 @@ struct msgb *icmpv6_construct_ra(const struct in6_addr *saddr,
        ra_opt_pref->preferred_lifetime = htonl(GGSN_AdvPreferredLifetime);
        ra_opt_pref->res2 = 0;
        memcpy(ra_opt_pref->prefix, prefix, sizeof(ra_opt_pref->prefix));
+       ra_opt_pref->prefix[10] ^= 0xff;

        /* checksum */
        skb_csum = csum_partial(msgb_data(msg), msgb_length(msg), 0);

Proposed solution:
Disable handling of routing advertisement by the kernel (SLAAC) and do it within sgsnemu [1].

This would work similar to what we already do in osmo-ggsn, but the other way around:
  • Upon IPv6 packet received in GTP tunnel from SGSN, where normally we'd then forward it to the tun device (encaps_tun()), instead we pass it to handle_router_mcast() (tun.c).
  • In handle_router_mcast(), if what we received is a RouterSolicitation, parse it and send back on the GTP tunnel a RouterAdvertisement: gtp_data_req(icmpv6_construct_ra())
So in sgsnemu case, the steps requried:
  1. Have a working setup with sgsnemu and osmo-ggsn
  2. Trigger the issue by applying the patch above mentioned to study the behavior
  3. Disable SLAAC (RouterAdvertisement) in the tun interface:
    1. Add a proc_ipv6_conf_write() function similar to the aleady available proc_ipv6_conf_read()
    2. Redo the checks on "accept_ra" and "forwarding" proc properties in create_pdp_conf().
  4. Send a RouterSolicitiation over the GTP tunnel using the IPv6 EUA received in PDPCreateContextResponse (create_pdp_conf()).
  5. Wait for RouterAdvertisement coming from the GTP tunnel, then set the IP address prefix from there (cb_tun_ind()).

Extra: This allows us to implement IPv6 builtin ping in sgsemu (like we do already for IPv4) without requiring the tun iface.


Also available in: Atom PDF

Add picture from clipboard (Maximum size: 48.8 MB)