pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-uecups/+/42457?usp=email )

Change subject: cups_client: Add commands to perform IPv6 SLAAC and obtain GTP 
tunnel IPv6 global info
......................................................................

cups_client: Add commands to perform IPv6 SLAAC and obtain GTP tunnel IPv6 
global info

Change-Id: I917b5c70f143d48b55b4e270e24594d1a36f71aa
---
M daemon/cups_client.c
M daemon/gtp_endpoint.c
M daemon/internal.h
M ttcn3/UECUPS_Types.ttcn
4 files changed, 158 insertions(+), 1 deletion(-)

Approvals:
  pespin: Looks good to me, approved
  fixeria: Looks good to me, but someone else must approve
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve




diff --git a/daemon/cups_client.c b/daemon/cups_client.c
index e283f23..f7c6f1a 100644
--- a/daemon/cups_client.c
+++ b/daemon/cups_client.c
@@ -133,6 +133,92 @@
        return jret;
 }

+json_t *gen_uecups_ep(const struct gtp_endpoint *ep)
+{
+       json_t *jret = json_object();
+       char *addr_type;
+       char ip_str[32+1];
+       uint16_t port;
+
+       switch (ep->bind_addr.u.sa.sa_family) {
+       case AF_INET:
+               addr_type = "IPV4";
+               osmo_hexdump_buf(ip_str, sizeof(ip_str),
+                               (const unsigned char 
*)&ep->bind_addr.u.sin.sin_addr,
+                               sizeof(ep->bind_addr.u.sin.sin_addr),
+                               "", true);
+               break;
+       case AF_INET6:
+               addr_type = "IPV6";
+               osmo_hexdump_buf(ip_str, sizeof(ip_str),
+                               (const unsigned char 
*)&ep->bind_addr.u.sin6.sin6_addr,
+                               sizeof(ep->bind_addr.u.sin6.sin6_addr),
+                               "", true);
+               break;
+       default:
+               OSMO_ASSERT(0);
+       }
+       port = osmo_sockaddr_port(&ep->bind_addr.u.sa);
+
+       json_object_set_new(jret, "addr_type", json_string(addr_type));
+       json_object_set_new(jret, "ip", json_string(ip_str));
+       json_object_set_new(jret, "Port", json_integer(port));
+
+       return jret;
+}
+
+void cc_ipv6_slaac_ind(const struct gtp_tunnel *t)
+{
+       struct gtp_endpoint *ep = t->gtp_ep;
+       struct cups_client *cc;
+       json_t *jtx = json_object();
+       json_t *jslaac_ind = json_object();
+       json_t *jep;
+       char *json_str = NULL;
+       unsigned int json_strlen;
+       char ipv6_str[32+1];
+
+       LOGP(DUECUPS, LOGL_INFO, "ipv6_slaac_ind\n");
+
+       OSMO_ASSERT(jtx);
+       OSMO_ASSERT(jslaac_ind);
+
+       json_object_set_new(jtx, "ipv6_slaac_ind", jslaac_ind);
+
+       jep = gen_uecups_ep(ep);
+       if (!jep)
+               goto free_ret;
+       json_object_set_new(jslaac_ind, "local_gtp_ep", jep);
+
+       json_object_set_new(jslaac_ind, "rx_teid", json_integer(t->rx_teid));
+
+       osmo_hexdump_buf(ipv6_str, sizeof(ipv6_str),
+                        (const unsigned char 
*)&t->user_addr_ipv6_prefix.u.sin6.sin6_addr,
+                        8, "", true);
+       json_object_set_new(jslaac_ind, "ipv6_prefix", json_string(ipv6_str));
+
+       osmo_hexdump_buf(ipv6_str, sizeof(ipv6_str),
+                       (const unsigned char *)&t->user_addr.u.sin6.sin6_addr,
+                       sizeof(t->user_addr.u.sin6.sin6_addr),
+                       "", true);
+       json_object_set_new(jslaac_ind, "ipv6_user_addr", 
json_string(ipv6_str));
+
+       json_str = json_dumps(jtx, JSON_SORT_KEYS);
+       if (!json_str) {
+               LOGT(t, LOGL_ERROR, "Error encoding JSON\n");
+               goto free_ret;
+       }
+       json_strlen = strlen(json_str);
+
+       llist_for_each_entry(cc, &t->d->cups_clients, list)
+               cups_client_tx_json_str(cc, json_str, json_strlen);
+
+free_ret:
+       if (jtx)
+               json_decref(jtx);
+       free(json_str);
+}
+
 static int parse_ep(struct osmo_sockaddr *out, json_t *in)
 {
        json_t *jaddr_type, *jport, *jip;
@@ -525,6 +611,38 @@
        return 0;
 }

+static int cups_client_handle_ipv6_slaac(struct cups_client *cc, json_t *cmd)
+{
+       struct osmo_sockaddr local_ep_addr;
+       json_t *jlocal_gtp_ep, *jrx_teid;
+       uint32_t rx_teid;
+       int rc;
+
+       jlocal_gtp_ep = json_object_get(cmd, "local_gtp_ep");
+       jrx_teid = json_object_get(cmd, "rx_teid");
+
+       if (!jlocal_gtp_ep || !jrx_teid)
+               return -EINVAL;
+
+       if (!json_is_object(jlocal_gtp_ep) || !json_is_integer(jrx_teid))
+               return -EINVAL;
+
+       rc = parse_ep(&local_ep_addr, jlocal_gtp_ep);
+       if (rc < 0)
+               return rc;
+       rx_teid = json_integer_value(jrx_teid);
+
+       rc = gtp_tunnel_tx_icmpv6_rs(g_daemon, &local_ep_addr, rx_teid);
+       if (rc < 0) {
+               LOGCC(cc, LOGL_NOTICE, "Failed to start IPv6 SLAAC\n");
+               cups_client_tx_json(cc, gen_uecups_result("ipv6_slaac_res", 
"ERR_IPv6_SLAAC_FAILED"));
+       } else {
+               cups_client_tx_json(cc, gen_uecups_result("ipv6_slaac_res", 
"OK"));
+       }
+
+       return 0;
+}
+
 static int cups_client_handle_json(struct cups_client *cc, json_t *jroot)
 {
        void *iter;
@@ -549,6 +667,8 @@
                rc = cups_client_handle_start_program(cc, cmd);
        } else if (!strcmp(key, "reset_all_state")) {
                rc = cups_client_handle_reset_all_state(cc, cmd);
+       } else if (!strcmp(key, "ipv6_slaac")) {
+               rc = cups_client_handle_ipv6_slaac(cc, cmd);
        } else {
                LOGCC(cc, LOGL_NOTICE, "Unknown command '%s' received\n", key);
                return -EINVAL;
diff --git a/daemon/gtp_endpoint.c b/daemon/gtp_endpoint.c
index 5d14e84..0332f91 100644
--- a/daemon/gtp_endpoint.c
+++ b/daemon/gtp_endpoint.c
@@ -87,6 +87,9 @@
                                     inet_ntop(AF_INET6, 
&t->user_addr.u.sin6.sin6_addr, &ip6strbuf[1][0], sizeof(ip6strbuf[1])),
                                     strerror(-rc));
                        }
+
+                       /* Notify cups_client about the new available IPv6 
prefix and global address: */
+                       cc_ipv6_slaac_ind(t);
                }
        }
 }
diff --git a/daemon/internal.h b/daemon/internal.h
index 2394e2c..5d4b832 100644
--- a/daemon/internal.h
+++ b/daemon/internal.h
@@ -155,6 +155,7 @@

 struct osmo_stream_srv_link *cups_srv_link_create(struct gtp_daemon *d);
 void child_terminated(struct gtp_daemon *d, int pid, int status);
+void cc_ipv6_slaac_ind(const struct gtp_tunnel *t);
 json_t *gen_uecups_result(const char *name, const char *res);
 int cups_client_tx_json(struct cups_client *cc, json_t *jtx);

diff --git a/ttcn3/UECUPS_Types.ttcn b/ttcn3/UECUPS_Types.ttcn
index 29fa738..45466c8 100644
--- a/ttcn3/UECUPS_Types.ttcn
+++ b/ttcn3/UECUPS_Types.ttcn
@@ -101,6 +101,27 @@
        UECUPS_Result   result
 };

+/* Perform IPv6 SLAAC on GTP-U tunnel to obtain IPv6 global IPv6 address for 
the UE */
+type record UECUPS_IPv6SLAAC {
+       /* local GTP endpoint + TEID are sufficient for unique identification */
+       UECUPS_SockAddr local_gtp_ep,
+       uint32_t        rx_teid
+};
+
+type record UECUPS_IPv6SLAACRes {
+       UECUPS_Result   result
+};
+
+/* Daemon informs us that IPv6 SLAAC was terminated */
+type record UECUPS_IPv6SLAACInd {
+       /* local GTP endpoint + TEID are sufficient for unique identification */
+       UECUPS_SockAddr local_gtp_ep,
+       uint32_t        rx_teid,
+       OCT8            ipv6_prefix,
+       OCT16           ipv6_user_addr
+};
+
+
 type union PDU_UECUPS {
        UECUPS_CreateTun        create_tun,
        UECUPS_CreateTunRes     create_tun_res,
@@ -113,7 +134,11 @@
        UECUPS_ProgramTermInd   program_term_ind,

        UeCUPS_ResetAllState    reset_all_state,
-       UeCUPS_ResetAllStateRes reset_all_state_res
+       UeCUPS_ResetAllStateRes reset_all_state_res,
+
+       UECUPS_IPv6SLAAC        ipv6_slaac,
+       UECUPS_IPv6SLAACRes     ipv6_slaac_res,
+       UECUPS_IPv6SLAACInd     ipv6_slaac_ind
 };


@@ -202,4 +227,12 @@
        tun_netns_name := tun_netns_name
 };

+template (value) UECUPS_IPv6SLAAC
+ts_UECUPS_IPv6SLAAC(template (value) UECUPS_SockAddr local_gtp_ep,
+                   template (value) uint32_t rx_teid)
+:= {
+       local_gtp_ep := local_gtp_ep,
+       rx_teid := rx_teid
+};
+
 } with { encode "JSON" };

--
To view, visit https://gerrit.osmocom.org/c/osmo-uecups/+/42457?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: osmo-uecups
Gerrit-Branch: master
Gerrit-Change-Id: I917b5c70f143d48b55b4e270e24594d1a36f71aa
Gerrit-Change-Number: 42457
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to