<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ggsn/+/17254">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">netns: Improve error checking<br><br>Change-Id: I9b9c8fd6eeaaa7d190b8e2a34ca82088904c7708<br>---<br>M lib/netns.c<br>M lib/netns.h<br>M sgsnemu/sgsnemu.c<br>3 files changed, 128 insertions(+), 61 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/lib/netns.c b/lib/netns.c</span><br><span>index 6734b5d..bd2076b 100644</span><br><span>--- a/lib/netns.c</span><br><span>+++ b/lib/netns.c</span><br><span>@@ -49,99 +49,133 @@</span><br><span> int switch_ns(int nsfd, sigset_t *oldmask)</span><br><span> {</span><br><span> sigset_t intmask;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigfillset(&intmask);</span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_BLOCK, &intmask, oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sigfillset(&intmask) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, oldmask)) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- return setns(nsfd, CLONE_NEWNET);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (setns(nsfd, CLONE_NEWNET) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void restore_ns(sigset_t *oldmask)</span><br><span style="color: hsl(120, 100%, 40%);">+int restore_ns(sigset_t *oldmask)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- setns(default_nsfd, CLONE_NEWNET);</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (setns(default_nsfd, CLONE_NEWNET) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_SETMASK, oldmask, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_SETMASK, oldmask, NULL)) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span> }</span><br><span> </span><br><span> int open_ns(int nsfd, const char *pathname, int flags)</span><br><span> {</span><br><span> sigset_t intmask, oldmask;</span><br><span> int fd;</span><br><span style="color: hsl(0, 100%, 40%);">- int errsv;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigfillset(&intmask);</span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_BLOCK, &intmask, &oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sigfillset(&intmask) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- setns(nsfd, CLONE_NEWNET);</span><br><span style="color: hsl(0, 100%, 40%);">- fd = open(pathname, flags);</span><br><span style="color: hsl(0, 100%, 40%);">- errsv = errno;</span><br><span style="color: hsl(0, 100%, 40%);">- setns(default_nsfd, CLONE_NEWNET);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (setns(nsfd, CLONE_NEWNET) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((fd = open(pathname, flags)) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (setns(default_nsfd, CLONE_NEWNET) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ close(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ close(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_SETMASK, &oldmask, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- errno = errsv;</span><br><span style="color: hsl(0, 100%, 40%);">- return fd;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span> }</span><br><span> </span><br><span> int socket_ns(int nsfd, int domain, int type, int protocol)</span><br><span> {</span><br><span> sigset_t intmask, oldmask;</span><br><span> int sk;</span><br><span style="color: hsl(0, 100%, 40%);">- int errsv;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigfillset(&intmask);</span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_BLOCK, &intmask, &oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sigfillset(&intmask) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- setns(nsfd, CLONE_NEWNET);</span><br><span style="color: hsl(0, 100%, 40%);">- sk = socket(domain, type, protocol);</span><br><span style="color: hsl(0, 100%, 40%);">- errsv = errno;</span><br><span style="color: hsl(0, 100%, 40%);">- setns(default_nsfd, CLONE_NEWNET);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (setns(nsfd, CLONE_NEWNET) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((sk = socket(domain, type, protocol)) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (setns(default_nsfd, CLONE_NEWNET) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ close(sk);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_SETMASK, &oldmask, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- errno = errsv;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ close(sk);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> return sk;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void init_netns()</span><br><span style="color: hsl(120, 100%, 40%);">+int init_netns()</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- if ((default_nsfd = open("/proc/self/ns/net", O_RDONLY)) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- perror("init_netns");</span><br><span style="color: hsl(0, 100%, 40%);">- exit(EXIT_FAILURE);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((default_nsfd = open("/proc/self/ns/net", O_RDONLY)) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span> }</span><br><span> </span><br><span> int get_nsfd(const char *name)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- int r;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ int fd;</span><br><span> sigset_t intmask, oldmask;</span><br><span> char path[MAXPATHLEN] = NETNS_PATH;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- r = mkdir(path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);</span><br><span style="color: hsl(0, 100%, 40%);">- if (r < 0 && errno != EEXIST)</span><br><span style="color: hsl(0, 100%, 40%);">- return r;</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = mkdir(path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 && errno != EEXIST)</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span> </span><br><span> snprintf(path, sizeof(path), "%s/%s", NETNS_PATH, name);</span><br><span style="color: hsl(0, 100%, 40%);">- r = open(path, O_RDONLY|O_CREAT|O_EXCL, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- if (r < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (errno == EEXIST)</span><br><span style="color: hsl(0, 100%, 40%);">- return open(path, O_RDONLY);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return r;</span><br><span style="color: hsl(120, 100%, 40%);">+ fd = open(path, O_RDONLY|O_CREAT|O_EXCL, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fd < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (errno == EEXIST) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((fd = open(path, O_RDONLY)) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ return fd;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- close(r);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (close(fd) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigfillset(&intmask);</span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_BLOCK, &intmask, &oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sigfillset(&intmask) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- unshare(CLONE_NEWNET);</span><br><span style="color: hsl(0, 100%, 40%);">- mount("/proc/self/ns/net", path, "none", MS_BIND, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (unshare(CLONE_NEWNET) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mount("/proc/self/ns/net", path, "none", MS_BIND, NULL) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- setns(default_nsfd, CLONE_NEWNET);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (setns(default_nsfd, CLONE_NEWNET) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sigprocmask(SIG_SETMASK, &oldmask, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- return open(path, O_RDONLY);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((fd = open(path, O_RDONLY)) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ return fd;</span><br><span> }</span><br><span> </span><br><span> #endif</span><br><span>diff --git a/lib/netns.h b/lib/netns.h</span><br><span>index 168e44f..3b91ba3 100644</span><br><span>--- a/lib/netns.h</span><br><span>+++ b/lib/netns.h</span><br><span>@@ -21,10 +21,10 @@</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void init_netns(void);</span><br><span style="color: hsl(120, 100%, 40%);">+int init_netns(void);</span><br><span> </span><br><span> int switch_ns(int nsfd, sigset_t *oldmask);</span><br><span style="color: hsl(0, 100%, 40%);">-void restore_ns(sigset_t *oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+int restore_ns(sigset_t *oldmask);</span><br><span> </span><br><span> int open_ns(int nsfd, const char *pathname, int flags);</span><br><span> int socket_ns(int nsfd, int domain, int type, int protocol);</span><br><span>diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c</span><br><span>index 2c0ce1b..fce5059 100644</span><br><span>--- a/sgsnemu/sgsnemu.c</span><br><span>+++ b/sgsnemu/sgsnemu.c</span><br><span>@@ -1323,19 +1323,29 @@</span><br><span> </span><br><span> static int delete_context(struct pdp_t *pdp)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (tun && options.ipdown) {</span><br><span> #if defined(__linux__)</span><br><span> sigset_t oldmask;</span><br><span> </span><br><span> if ((options.netns)) {</span><br><span style="color: hsl(0, 100%, 40%);">- switch_ns(netns, &oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = switch_ns(netns, &oldmask)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Failed to switch to netns %s: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ options.netns, strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> #endif</span><br><span> tun_runscript(tun, options.ipdown);</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span> if ((options.netns)) {</span><br><span style="color: hsl(0, 100%, 40%);">- restore_ns(&oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = restore_ns(&oldmask)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Failed to switch to original netns: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> #endif</span><br><span> }</span><br><span>@@ -1399,6 +1409,7 @@</span><br><span> </span><br><span> static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span> struct in46_addr addr;</span><br><span> #if defined(__linux__)</span><br><span> sigset_t oldmask;</span><br><span>@@ -1458,7 +1469,11 @@</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span> if ((options.createif) && (options.netns)) {</span><br><span style="color: hsl(0, 100%, 40%);">- switch_ns(netns, &oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = switch_ns(netns, &oldmask)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Failed to switch to netns %s: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ options.netns, strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span>@@ -1504,7 +1519,10 @@</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span> if ((options.createif) && (options.netns)) {</span><br><span style="color: hsl(0, 100%, 40%);">- restore_ns(&oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = restore_ns(&oldmask)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0, "Failed to switch to original netns: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span>@@ -1572,7 +1590,7 @@</span><br><span> fd_set fds; /* For select() */</span><br><span> struct timeval idleTime; /* How long to select() */</span><br><span> struct pdp_t *pdp;</span><br><span style="color: hsl(0, 100%, 40%);">- int n;</span><br><span style="color: hsl(120, 100%, 40%);">+ int n, rc;</span><br><span> int starttime = time(NULL); /* Time program was started */</span><br><span> int stoptime = 0; /* Time to exit */</span><br><span> int pingtimeout = 0; /* Time to print ping statistics */</span><br><span>@@ -1594,7 +1612,10 @@</span><br><span> osmo_init_logging2(tall_sgsnemu_ctx, &log_info);</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span style="color: hsl(0, 100%, 40%);">- init_netns();</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = init_netns()) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0, "Failed to initialize netns: %s", strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> #endif</span><br><span> </span><br><span> /* Process options given in configuration file and command line */</span><br><span>@@ -1622,8 +1643,16 @@</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span> if ((options.createif) && (options.netns)) {</span><br><span style="color: hsl(0, 100%, 40%);">- netns = get_nsfd(options.netns);</span><br><span style="color: hsl(0, 100%, 40%);">- switch_ns(netns, &oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((netns = get_nsfd(options.netns)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0, "Failed to obtain fd for netns %s: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ options.netns, strerror(-netns));</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = switch_ns(netns, &oldmask)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0, "Failed to switch to netns %s: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ options.netns, strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span>@@ -1654,7 +1683,11 @@</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span> if ((options.createif) && (options.netns)) {</span><br><span style="color: hsl(0, 100%, 40%);">- restore_ns(&oldmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = restore_ns(&oldmask)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ SYS_ERR(DSGSN, LOGL_ERROR, 0, "Failed to switch to original netns: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ggsn/+/17254">change 17254</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/c/osmo-ggsn/+/17254"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-ggsn </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I9b9c8fd6eeaaa7d190b8e2a34ca82088904c7708 </div>
<div style="display:none"> Gerrit-Change-Number: 17254 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>