<p>Stefan Sperling has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/12228">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">disable recording of LU timestamps by default<br><br>Add VTY commands which enable or disable recording of<br>Location Update timestamps in the HLR database.<br><br>Because this feature has implications for the privacy of<br>network users, it is now off by default. It needs to be<br>explicitly enabled by the administrator who will see a<br>warning about potential privacy concerns when doing so.<br><br>The new commands added to the hlr configuration space are:<br><br>  record-lu-timestamps<br>  no record-lu-timestamps<br><br>DB tests keep recording timestamps in the test database to<br>ensure that the corresponding code is being exercised.<br><br>Change-Id: I2f18b5ddc9b4b8e1174c6dea71cddf1c8d2230df<br>Related: OS#2838<br>Depends: Ie180c434f02ffec0d4b2f651a73258a8126b2e1a<br>---<br>M src/db.h<br>M src/db_hlr.c<br>M src/hlr.c<br>M src/hlr.h<br>M src/hlr_vty.c<br>M tests/db/db_test.c<br>M tests/db/db_test.err<br>7 files changed, 63 insertions(+), 31 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/28/12228/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/db.h b/src/db.h</span><br><span>index ae592fb..2439196 100644</span><br><span>--- a/src/db.h</span><br><span>+++ b/src/db.h</span><br><span>@@ -131,7 +131,7 @@</span><br><span>                  struct hlr_subscriber *subscr);</span><br><span> int db_subscr_nam(struct db_context *dbc, const char *imsi, bool nam_val, bool is_ps);</span><br><span> int db_subscr_lu(struct db_context *dbc, int64_t subscr_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                 const char *vlr_or_sgsn_number, bool is_ps);</span><br><span style="color: hsl(120, 100%, 40%);">+          const char *vlr_or_sgsn_number, bool is_ps, bool record_timestamp);</span><br><span> </span><br><span> int db_subscr_purge(struct db_context *dbc, const char *by_imsi,</span><br><span>                     bool purge_val, bool is_ps);</span><br><span>diff --git a/src/db_hlr.c b/src/db_hlr.c</span><br><span>index c6293f9..dd80aaf 100644</span><br><span>--- a/src/db_hlr.c</span><br><span>+++ b/src/db_hlr.c</span><br><span>@@ -591,11 +591,12 @@</span><br><span>  * \param[in] subscr_id  ID of the subscriber in the HLR db.</span><br><span>  * \param[in] vlr_or_sgsn_number  ASCII string of identifier digits.</span><br><span>  * \param[in] is_ps  when true, set sgsn_number, else set vlr_number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] record_timestamp  if true, then store LU timestamp in the HLR db</span><br><span>  * \returns 0 on success, -ENOENT when the given subscriber does not exist,</span><br><span>  *         -EIO on database errors.</span><br><span>  */</span><br><span> int db_subscr_lu(struct db_context *dbc, int64_t subscr_id,</span><br><span style="color: hsl(0, 100%, 40%);">-               const char *vlr_or_sgsn_number, bool is_ps)</span><br><span style="color: hsl(120, 100%, 40%);">+           const char *vlr_or_sgsn_number, bool is_ps, bool record_timestamp)</span><br><span> {</span><br><span>     sqlite3_stmt *stmt;</span><br><span>  int rc, ret = 0;</span><br><span>@@ -637,6 +638,9 @@</span><br><span> </span><br><span>   db_remove_reset(stmt);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    if (!record_timestamp)</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (osmo_clock_gettime(CLOCK_REALTIME, &localtime) != 0) {</span><br><span>               LOGP(DAUC, LOGL_ERROR, "Cannot get the current time: (%d) %s\n", errno, strerror(errno));</span><br><span>          ret = -errno;</span><br><span>diff --git a/src/hlr.c b/src/hlr.c</span><br><span>index 4873a66..5020eae 100644</span><br><span>--- a/src/hlr.c</span><br><span>+++ b/src/hlr.c</span><br><span>@@ -325,7 +325,7 @@</span><br><span>         LOGP(DAUC, LOGL_DEBUG, "IMSI='%s': storing %s = %s\n",</span><br><span>          subscr->imsi, luop->is_ps ? "SGSN number" : "VLR number",</span><br><span>          osmo_quote_str((const char*)luop->peer, -1));</span><br><span style="color: hsl(0, 100%, 40%);">-   if (db_subscr_lu(g_hlr->dbc, subscr->id, (const char *)luop->peer, luop->is_ps))</span><br><span style="color: hsl(120, 100%, 40%);">+  if (db_subscr_lu(g_hlr->dbc, subscr->id, (const char *)luop->peer, luop->is_ps, g_hlr->record_lu_timestamps))</span><br><span>                 LOGP(DAUC, LOGL_ERROR, "IMSI='%s': Cannot update %s in the database\n",</span><br><span>                 subscr->imsi, luop->is_ps ? "SGSN number" : "VLR number");</span><br><span> </span><br><span>@@ -614,6 +614,9 @@</span><br><span>  /* Init default (call independent) SS session guard timeout value */</span><br><span>         g_hlr->ncss_guard_timeout = NCSS_GUARD_TIMEOUT_DEFAULT;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        /* Do not record location update timestamps by default. */</span><br><span style="color: hsl(120, 100%, 40%);">+    g_hlr->record_lu_timestamps = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    rc = osmo_init_logging2(hlr_ctx, &hlr_log_info);</span><br><span>         if (rc < 0) {</span><br><span>             fprintf(stderr, "Error initializing logging\n");</span><br><span>diff --git a/src/hlr.h b/src/hlr.h</span><br><span>index e9cc747..7add8b7 100644</span><br><span>--- a/src/hlr.h</span><br><span>+++ b/src/hlr.h</span><br><span>@@ -51,6 +51,9 @@</span><br><span>      struct llist_head ussd_routes;</span><br><span> </span><br><span>   struct llist_head ss_sessions;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Shall we store Location Update timestamps in the database? */</span><br><span style="color: hsl(120, 100%, 40%);">+      bool record_lu_timestamps;</span><br><span> };</span><br><span> </span><br><span> extern struct hlr *g_hlr;</span><br><span>diff --git a/src/hlr_vty.c b/src/hlr_vty.c</span><br><span>index 6706aa4..d3caad5 100644</span><br><span>--- a/src/hlr_vty.c</span><br><span>+++ b/src/hlr_vty.c</span><br><span>@@ -71,6 +71,8 @@</span><br><span> static int config_write_hlr(struct vty *vty)</span><br><span> {</span><br><span>  vty_out(vty, "hlr%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (g_hlr->record_lu_timestamps)</span><br><span style="color: hsl(120, 100%, 40%);">+           vty_out(vty, " record-lu-timestamps%s", VTY_NEWLINE);</span><br><span>      return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -123,6 +125,24 @@</span><br><span>  return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_record_lu_timestamps, cfg_record_lu_timestamps_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+   "record-lu-timestamps",</span><br><span style="color: hsl(120, 100%, 40%);">+     "Record timestamps of Location Updates in the HLR database (off by default)")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    g_hlr->record_lu_timestamps = true;</span><br><span style="color: hsl(120, 100%, 40%);">+        vty_out(vty, "Timestamps of Location Updates will be stored in the HLR database.%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+  vty_out(vty, "Please carefully consider the privacy implications of recording the activity of your users!%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_no_record_lu_timestamps, cfg_no_record_lu_timestamps_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "no record-lu-timestamps",</span><br><span style="color: hsl(120, 100%, 40%);">+  NO_STR "Record timestamps of Location Updates in the HLR database")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      g_hlr->record_lu_timestamps = false;</span><br><span style="color: hsl(120, 100%, 40%);">+       return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /***********************************************************************</span><br><span>  * USSD Entity</span><br><span>  ***********************************************************************/</span><br><span>@@ -353,6 +373,8 @@</span><br><span> </span><br><span>        install_element(CONFIG_NODE, &cfg_hlr_cmd);</span><br><span>      install_node(&hlr_node, config_write_hlr);</span><br><span style="color: hsl(120, 100%, 40%);">+        install_element(HLR_NODE, &cfg_record_lu_timestamps_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(HLR_NODE, &cfg_no_record_lu_timestamps_cmd);</span><br><span> </span><br><span>         install_element(HLR_NODE, &cfg_gsup_cmd);</span><br><span>        install_node(&gsup_node, config_write_hlr_gsup);</span><br><span>diff --git a/tests/db/db_test.c b/tests/db/db_test.c</span><br><span>index c4ed6ed..e90661d 100644</span><br><span>--- a/tests/db/db_test.c</span><br><span>+++ b/tests/db/db_test.c</span><br><span>@@ -337,39 +337,39 @@</span><br><span> </span><br><span>        comment("Record LU for PS and CS (SGSN and VLR names)");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  ASSERT_RC(db_subscr_lu(dbc, id0, "5952", true), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASSERT_RC(db_subscr_lu(dbc, id0, "5952", true, true), 0);</span><br><span>  ASSERT_SEL(id, id0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ASSERT_RC(db_subscr_lu(dbc, id0, "712", false), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASSERT_RC(db_subscr_lu(dbc, id0, "712", false, true), 0);</span><br><span>  ASSERT_SEL(id, id0, 0);</span><br><span> </span><br><span>  comment("Record LU for PS and CS (SGSN and VLR names) *again*");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  ASSERT_RC(db_subscr_lu(dbc, id0, "111", true), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  ASSERT_RC(db_subscr_lu(dbc, id0, "111", true, true), 0);</span><br><span>   ASSERT_SEL(id, id0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ASSERT_RC(db_subscr_lu(dbc, id0, "111", true), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  ASSERT_RC(db_subscr_lu(dbc, id0, "111", true, true), 0);</span><br><span>   ASSERT_SEL(id, id0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ASSERT_RC(db_subscr_lu(dbc, id0, "222", false), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASSERT_RC(db_subscr_lu(dbc, id0, "222", false, true), 0);</span><br><span>  ASSERT_SEL(id, id0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ASSERT_RC(db_subscr_lu(dbc, id0, "222", false), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASSERT_RC(db_subscr_lu(dbc, id0, "222", false, true), 0);</span><br><span>  ASSERT_SEL(id, id0, 0);</span><br><span> </span><br><span>  comment("Unset LU info for PS and CS (SGSN and VLR names)");</span><br><span style="color: hsl(0, 100%, 40%);">-  ASSERT_RC(db_subscr_lu(dbc, id0, "", true), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     ASSERT_RC(db_subscr_lu(dbc, id0, "", true, true), 0);</span><br><span>      ASSERT_SEL(id, id0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ASSERT_RC(db_subscr_lu(dbc, id0, "", false), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    ASSERT_RC(db_subscr_lu(dbc, id0, "", false, true), 0);</span><br><span>     ASSERT_SEL(id, id0, 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     ASSERT_RC(db_subscr_lu(dbc, id0, "111", true), 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    ASSERT_RC(db_subscr_lu(dbc, id0, "222", false), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASSERT_RC(db_subscr_lu(dbc, id0, "111", true, true), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    ASSERT_RC(db_subscr_lu(dbc, id0, "222", false, true), 0);</span><br><span>  ASSERT_SEL(id, id0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ASSERT_RC(db_subscr_lu(dbc, id0, NULL, true), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     ASSERT_RC(db_subscr_lu(dbc, id0, NULL, true, true), 0);</span><br><span>      ASSERT_SEL(id, id0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ASSERT_RC(db_subscr_lu(dbc, id0, NULL, false), 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    ASSERT_RC(db_subscr_lu(dbc, id0, NULL, false, true), 0);</span><br><span>     ASSERT_SEL(id, id0, 0);</span><br><span> </span><br><span>  comment("Record LU for non-existent ID");</span><br><span style="color: hsl(0, 100%, 40%);">-     ASSERT_RC(db_subscr_lu(dbc, 99999, "5952", true), -ENOENT);</span><br><span style="color: hsl(0, 100%, 40%);">-   ASSERT_RC(db_subscr_lu(dbc, 99999, "712", false), -ENOENT);</span><br><span style="color: hsl(120, 100%, 40%);">+ ASSERT_RC(db_subscr_lu(dbc, 99999, "5952", true, true), -ENOENT);</span><br><span style="color: hsl(120, 100%, 40%);">+   ASSERT_RC(db_subscr_lu(dbc, 99999, "712", false, true), -ENOENT);</span><br><span>  ASSERT_SEL(id, 99999, -ENOENT);</span><br><span> </span><br><span>  comment("Purge and un-purge PS and CS");</span><br><span>diff --git a/tests/db/db_test.err b/tests/db/db_test.err</span><br><span>index 1d34045..d556102 100644</span><br><span>--- a/tests/db/db_test.err</span><br><span>+++ b/tests/db/db_test.err</span><br><span>@@ -373,7 +373,7 @@</span><br><span> </span><br><span> --- Record LU for PS and CS (SGSN and VLR names)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "5952", true) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "5952", true, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -383,7 +383,7 @@</span><br><span>   .sgsn_number = '5952',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "712", false) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "712", false, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -397,7 +397,7 @@</span><br><span> </span><br><span> --- Record LU for PS and CS (SGSN and VLR names) *again*</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "111", true) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "111", true, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -408,7 +408,7 @@</span><br><span>   .sgsn_number = '111',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "111", true) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "111", true, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -419,7 +419,7 @@</span><br><span>   .sgsn_number = '111',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "222", false) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "222", false, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -430,7 +430,7 @@</span><br><span>   .sgsn_number = '111',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "222", false) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "222", false, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -444,7 +444,7 @@</span><br><span> </span><br><span> --- Unset LU info for PS and CS (SGSN and VLR names)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "", true) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "", true, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -454,7 +454,7 @@</span><br><span>   .vlr_number = '222',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "", false) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "", false, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -463,9 +463,9 @@</span><br><span>   .msisdn = '543210123456789',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "111", true) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "111", true, true) --> 0</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, "222", false) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, "222", false, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -476,7 +476,7 @@</span><br><span>   .sgsn_number = '111',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, NULL, true) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, NULL, true, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -486,7 +486,7 @@</span><br><span>   .vlr_number = '222',</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, id0, NULL, false) --> 0</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, id0, NULL, false, true) --> 0</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0</span><br><span> struct hlr_subscriber {</span><br><span>@@ -498,10 +498,10 @@</span><br><span> </span><br><span> --- Record LU for non-existent ID</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, 99999, "5952", true) --> -ENOENT</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, 99999, "5952", true, true) --> -ENOENT</span><br><span> DAUC Cannot update SGSN number for subscriber ID=99999: no such subscriber</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-db_subscr_lu(dbc, 99999, "712", false) --> -ENOENT</span><br><span style="color: hsl(120, 100%, 40%);">+db_subscr_lu(dbc, 99999, "712", false, true) --> -ENOENT</span><br><span> DAUC Cannot update VLR number for subscriber ID=99999: no such subscriber</span><br><span> </span><br><span> db_subscr_get_by_id(dbc, 99999, &g_subscr) --> -ENOENT</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12228">change 12228</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12228"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-hlr </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I2f18b5ddc9b4b8e1174c6dea71cddf1c8d2230df </div>
<div style="display:none"> Gerrit-Change-Number: 12228 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Stefan Sperling <stsp@stsp.name> </div>