Change in osmo-mgw[master]: mgw: Initial IPv6 support

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Thu Sep 3 13:03:57 UTC 2020


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-mgw/+/19969 )


Change subject: mgw: Initial IPv6 support
......................................................................

mgw: Initial IPv6 support

This commit contains the bulky work of moving all address parsing to
support IPv6 together with IPv4.
Some specific patches required for full IPv6+IPv4 support requiring
behavioral changes come after this one.

Full Osmux IPv6 support is left out of the scope of this patch.

Depends: libosmocore.git Ie07a38b05b7888885dba4ae795e9f3d9a561543d (> 1.4.0)
Depends: libosmocore.git I59bf4b4b3ed14766a5a5285923d1ffa9fc8b2294 (> 1.4.0)
Change-Id: I504ca776d88fd852bbaef07060c125980db3fdd7
---
M include/osmocom/mgcp/mgcp.h
M include/osmocom/mgcp/mgcp_endp.h
M include/osmocom/mgcp/mgcp_network.h
M include/osmocom/mgcp/osmux.h
M src/libosmo-mgcp/mgcp_conn.c
M src/libosmo-mgcp/mgcp_network.c
M src/libosmo-mgcp/mgcp_osmux.c
M src/libosmo-mgcp/mgcp_protocol.c
M src/libosmo-mgcp/mgcp_sdp.c
M src/libosmo-mgcp/mgcp_vty.c
M src/osmo-mgw/mgw_main.c
M tests/mgcp/mgcp_test.c
12 files changed, 281 insertions(+), 117 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/69/19969/1

diff --git a/include/osmocom/mgcp/mgcp.h b/include/osmocom/mgcp/mgcp.h
index 33bfe71..75e531b 100644
--- a/include/osmocom/mgcp/mgcp.h
+++ b/include/osmocom/mgcp/mgcp.h
@@ -23,6 +23,7 @@
 #pragma once
 
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/socket.h>
 #include <osmocom/core/write_queue.h>
 #include <osmocom/core/timer.h>
 #include <osmocom/core/logging.h>
@@ -207,4 +208,4 @@
 
 
 int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port);
-int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len);
+int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, char *buf, int len);
diff --git a/include/osmocom/mgcp/mgcp_endp.h b/include/osmocom/mgcp/mgcp_endp.h
index 065494f..14cae25 100644
--- a/include/osmocom/mgcp/mgcp_endp.h
+++ b/include/osmocom/mgcp/mgcp_endp.h
@@ -26,7 +26,7 @@
 #include <osmocom/core/msgb.h>
 #include <osmocom/gsm/i460_mux.h>
 
-struct sockaddr_in;
+struct sockaddr;
 struct mgcp_conn;
 struct mgcp_conn_rtp;
 struct mgcp_endpoint;
@@ -42,7 +42,7 @@
 struct osmo_rtp_msg_ctx {
 	int proto;
 	struct mgcp_conn_rtp *conn_src;
-	struct sockaddr_in *from_addr;
+	struct osmo_sockaddr *from_addr;
 };
 
 #define OSMO_RTP_MSG_CTX(MSGB) ((struct osmo_rtp_msg_ctx*)(MSGB)->cb)
diff --git a/include/osmocom/mgcp/mgcp_network.h b/include/osmocom/mgcp/mgcp_network.h
index c4967eb..9674445 100644
--- a/include/osmocom/mgcp/mgcp_network.h
+++ b/include/osmocom/mgcp/mgcp_network.h
@@ -2,6 +2,9 @@
 
 #include <inttypes.h>
 #include <stdbool.h>
+
+#include <osmocom/core/socket.h>
+
 #include <osmocom/mgcp/mgcp.h>
 
 #define MGCP_DUMMY_LOAD 0x23
@@ -79,7 +82,7 @@
 /* 'mgcp_rtp_end': basically a wrapper around the RTP+RTCP ports */
 struct mgcp_rtp_end {
 	/* remote IP address of the RTP socket */
-	struct in_addr addr;
+	struct osmo_sockaddr addr;
 
 	/* in network byte order */
 	int rtp_port, rtcp_port;
@@ -121,12 +124,12 @@
 	/* is this tap active (1) or not (0) */
 	int enabled;
 	/* IP/port to which we're forwarding the tapped data */
-	struct sockaddr_in forward;
+	struct osmo_sockaddr forward;
 };
 
 struct mgcp_conn;
 
-int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,
+int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,
 	      struct msgb *msg, struct mgcp_conn_rtp *conn_src,
 	      struct mgcp_conn_rtp *conn_dst);
 int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);
@@ -140,7 +143,7 @@
 void mgcp_patch_and_count(struct mgcp_endpoint *endp,
 			  struct mgcp_rtp_state *state,
 			  struct mgcp_rtp_end *rtp_end,
-			  struct sockaddr_in *addr, struct msgb *msg);
+			  struct osmo_sockaddr *addr, struct msgb *msg);
 void mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn);
 int mgcp_set_ip_tos(int fd, int tos);
 
diff --git a/include/osmocom/mgcp/osmux.h b/include/osmocom/mgcp/osmux.h
index 69ba3d0..99b44d1 100644
--- a/include/osmocom/mgcp/osmux.h
+++ b/include/osmocom/mgcp/osmux.h
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <osmocom/core/socket.h>
 
 #include <osmocom/netif/osmux.h>
 struct mgcp_conn_rtp;
@@ -13,7 +14,7 @@
 
 int osmux_init(int role, struct mgcp_config *cfg);
 int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
-		      struct in_addr *addr, uint16_t port);
+		      struct osmo_sockaddr *addr, uint16_t port);
 void conn_osmux_disable(struct mgcp_conn_rtp *conn);
 int conn_osmux_allocate_cid(struct mgcp_conn_rtp *conn, int osmux_cid);
 void conn_osmux_release_cid(struct mgcp_conn_rtp *conn);
diff --git a/src/libosmo-mgcp/mgcp_conn.c b/src/libosmo-mgcp/mgcp_conn.c
index d52fa64..328e580 100644
--- a/src/libosmo-mgcp/mgcp_conn.c
+++ b/src/libosmo-mgcp/mgcp_conn.c
@@ -349,6 +349,7 @@
 char *mgcp_conn_dump(struct mgcp_conn *conn)
 {
 	static char str[sizeof(conn->name)+sizeof(conn->id)+256];
+	char ipbuf[INET6_ADDRSTRLEN];
 
 	if (!conn) {
 		snprintf(str, sizeof(str), "(null connection)");
@@ -362,7 +363,7 @@
 			 "rtp:%u rtcp:%u)",
 			 conn->name,
 			 conn->id,
-			 inet_ntoa(conn->u.rtp.end.addr),
+			 osmo_sockaddr_ntop(&conn->u.rtp.end.addr.u.sa, ipbuf),
 			 ntohs(conn->u.rtp.end.rtp_port),
 			 ntohs(conn->u.rtp.end.rtcp_port));
 		break;
diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c
index 712c706..756ae2a 100644
--- a/src/libosmo-mgcp/mgcp_network.c
+++ b/src/libosmo-mgcp/mgcp_network.c
@@ -77,6 +77,16 @@
 
 static int rx_rtp(struct msgb *msg);
 
+static bool addr_is_any(struct osmo_sockaddr *osa) {
+	if (osa->u.sa.sa_family == AF_INET6) {
+		struct in6_addr ip6_any = IN6ADDR_ANY_INIT;
+		return memcmp(&osa->u.sin6.sin6_addr,
+				   &ip6_any, sizeof(ip6_any)) == 0;
+	} else {
+		return osa->u.sin.sin_addr.s_addr == 0;
+	}
+}
+
 /*! Determine the local rtp bind IP-address.
  *  \param[out] addr caller provided memory to store the resulting IP-Address.
  *  \param[in] endp mgcp endpoint, that holds a copy of the VTY parameters.
@@ -89,19 +99,20 @@
 {
 
 	struct mgcp_endpoint *endp;
+	char ipbuf[INET6_ADDRSTRLEN];
 	int rc;
 	endp = conn->conn->endp;
 
 	/* Try probing the local IP-Address */
-	if (endp->cfg->net_ports.bind_addr_probe && conn->end.addr.s_addr != 0) {
-		rc = osmo_sock_local_ip(addr, inet_ntoa(conn->end.addr));
+	if (endp->cfg->net_ports.bind_addr_probe && !addr_is_any(&conn->end.addr)) {
+		rc = osmo_sock_local_ip(addr, osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));
 		if (rc < 0)
 			LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
 				 "local interface auto detection failed, using configured addresses...\n");
 		else {
 			LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
 				 "selected local rtp bind ip %s by probing using remote ip %s\n",
-				 addr, inet_ntoa(conn->end.addr));
+				 addr, osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));
 			return;
 		}
 	}
@@ -110,7 +121,7 @@
 	if (endp->cfg->net_ports.bind_addr) {
 		/* Check there is a bind IP for the RTP traffic configured,
 		 * if so, use that IP-Address */
-		osmo_strlcpy(addr, endp->cfg->net_ports.bind_addr, INET_ADDRSTRLEN);
+		osmo_strlcpy(addr, endp->cfg->net_ports.bind_addr, INET6_ADDRSTRLEN);
 		LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
 			 "using configured rtp bind ip as local bind ip %s\n",
 			 addr);
@@ -118,7 +129,7 @@
 		/* No specific bind IP is configured for the RTP traffic, so
 		 * assume the IP where we listen for incoming MGCP messages
 		 * as bind IP */
-		osmo_strlcpy(addr, endp->cfg->source_addr, INET_ADDRSTRLEN);
+		osmo_strlcpy(addr, endp->cfg->source_addr, INET6_ADDRSTRLEN);
 		LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
 			"using mgcp bind ip as local rtp bind ip: %s\n", addr);
 	}
@@ -154,19 +165,26 @@
  *  \param[in] buf buffer that holds the data to be send.
  *  \param[in] len length of the data to be sent.
  *  \returns bytes sent, -1 on error. */
-int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
+int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, char *buf, int len)
 {
-	struct sockaddr_in out;
+	char ipbuf[INET6_ADDRSTRLEN];
+	size_t addr_len;
+	bool is_ipv6 =  addr->u.sa.sa_family == AF_INET6;
 
 	LOGP(DRTP, LOGL_DEBUG,
-	     "sending %i bytes length packet to %s:%u ...\n",
-	     len, inet_ntoa(*addr), ntohs(port));
+	     "sending %i bytes length packet to %s:%u ...\n", len,
+	     osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+	     ntohs(port));
 
-	out.sin_family = AF_INET;
-	out.sin_port = port;
-	memcpy(&out.sin_addr, addr, sizeof(*addr));
+	if (is_ipv6) {
+		addr->u.sin6.sin6_port = port;
+		addr_len = sizeof(addr->u.sin6);
+	} else {
+		addr->u.sin.sin_port = port;
+		addr_len = sizeof(addr->u.sin);
+	}
 
-	return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
+	return sendto(fd, buf, len, 0, &addr->u.sa, addr_len);
 }
 
 /*! send RTP dummy packet (to keep NAT connection open).
@@ -229,12 +247,13 @@
 			       struct mgcp_rtp_state *state,
 			       struct mgcp_rtp_stream_state *sstate,
 			       struct mgcp_rtp_end *rtp_end,
-			       struct sockaddr_in *addr,
+			       struct osmo_sockaddr *addr,
 			       uint16_t seq, uint32_t timestamp,
 			       const char *text, int32_t * tsdelta_out)
 {
 	int32_t tsdelta;
 	int32_t timestamp_error;
+	char ipbuf[INET6_ADDRSTRLEN];
 
 	/* Not fully intialized, skip */
 	if (sstate->last_tsdelta == 0 && timestamp == sstate->last_timestamp)
@@ -251,8 +270,9 @@
 				 "from %s:%d\n",
 				 text, seq,
 				 state->patch.timestamp_offset, state->patch.seq_offset,
-				 sstate->ssrc, timestamp, inet_ntoa(addr->sin_addr),
-				 ntohs(addr->sin_port));
+				 sstate->ssrc, timestamp,
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+				 osmo_sockaddr_port(&addr->u.sa));
 		}
 		return 0;
 	}
@@ -267,9 +287,9 @@
 			 "The %s timestamp delta is %d "
 			 "on SSRC: %u timestamp: %u "
 			 "from %s:%d\n",
-			 text, tsdelta,
-			 sstate->ssrc, timestamp,
-			 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+			 text, tsdelta, sstate->ssrc, timestamp,
+			 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+			 osmo_sockaddr_port(&addr->u.sa));
 
 		return 0;
 	}
@@ -281,7 +301,8 @@
 				 "on SSRC: %u timestamp: %u from %s:%d\n",
 				 text, sstate->last_tsdelta, tsdelta,
 				 sstate->ssrc, timestamp,
-				 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+				 osmo_sockaddr_port(&addr->u.sa));
 		}
 	}
 
@@ -303,7 +324,8 @@
 			 (int16_t)(seq - sstate->last_seq),
 			 (int32_t)(timestamp - sstate->last_timestamp),
 			 tsdelta,
-			 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
+			 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+			 osmo_sockaddr_port(&addr->u.sa),
 			 state->packet_duration);
 	}
 	return 1;
@@ -313,12 +335,13 @@
 static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
 				       struct mgcp_rtp_state *state,
 				       struct mgcp_rtp_end *rtp_end,
-				       struct sockaddr_in *addr,
+				       struct osmo_sockaddr *addr,
 				       int16_t delta_seq, uint32_t in_timestamp)
 {
 	int32_t tsdelta = state->packet_duration;
 	int timestamp_offset;
 	uint32_t out_timestamp;
+	char ipbuf[INET6_ADDRSTRLEN];
 
 	if (tsdelta == 0) {
 		tsdelta = state->out_stream.last_tsdelta;
@@ -327,7 +350,8 @@
 				 "A fixed packet duration is not available, "
 				 "using last output timestamp delta instead: %d "
 				 "from %s:%d\n", tsdelta,
-				 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+				 osmo_sockaddr_port(&addr->u.sa));
 		} else {
 			tsdelta = rtp_end->codec->rate * 20 / 1000;
 			LOGPENDP(endp, DRTP, LOGL_NOTICE,
@@ -335,7 +359,8 @@
 				 "are not available, "
 				 "using fixed 20ms instead: %d "
 				 "from %s:%d\n", tsdelta,
-				 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+				 osmo_sockaddr_port(&addr->u.sa));
 		}
 	}
 
@@ -344,13 +369,13 @@
 
 	if (state->patch.timestamp_offset != timestamp_offset) {
 		state->patch.timestamp_offset = timestamp_offset;
-
 		LOGPENDP(endp, DRTP, LOGL_NOTICE,
 			 "Timestamp offset change on SSRC: %u "
 			 "SeqNo delta: %d, TS offset: %d, "
 			 "from %s:%d\n", state->in_stream.ssrc,
 			 delta_seq, state->patch.timestamp_offset,
-			 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+			 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+			 osmo_sockaddr_port(&addr->u.sa));
 	}
 
 	return timestamp_offset;
@@ -360,9 +385,10 @@
 static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp,
 				      struct mgcp_rtp_state *state,
 				      struct mgcp_rtp_end *rtp_end,
-				      struct sockaddr_in *addr,
+				      struct osmo_sockaddr *addr,
 				      uint32_t timestamp)
 {
+	char ipbuf[INET6_ADDRSTRLEN];
 	int ts_error = 0;
 	int ts_check = 0;
 	int ptime = state->packet_duration;
@@ -375,14 +401,14 @@
 	/* If there is an alignment error, we have to compensate it */
 	if (ts_error) {
 		state->patch.timestamp_offset += ptime - ts_error;
-
 		LOGPENDP(endp, DRTP, LOGL_NOTICE,
 			 "Corrected timestamp alignment error of %d on SSRC: %u "
 			 "new TS offset: %d, "
 			 "from %s:%d\n",
 			 ts_error, state->in_stream.ssrc,
-			 state->patch.timestamp_offset, inet_ntoa(addr->sin_addr),
-			 ntohs(addr->sin_port));
+			 state->patch.timestamp_offset,
+			 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+			 osmo_sockaddr_port(&addr->u.sa));
 	}
 
 	/* Check we really managed to compensate the timestamp
@@ -521,8 +547,9 @@
 void mgcp_patch_and_count(struct mgcp_endpoint *endp,
 			  struct mgcp_rtp_state *state,
 			  struct mgcp_rtp_end *rtp_end,
-			  struct sockaddr_in *addr, struct msgb *msg)
+			  struct osmo_sockaddr *addr, struct msgb *msg)
 {
+	char ipbuf[INET6_ADDRSTRLEN];
 	uint32_t arrival_time;
 	int32_t transit;
 	uint16_t seq;
@@ -560,7 +587,8 @@
 			 "pkt-duration: %d, from %s:%d\n",
 			 state->in_stream.ssrc,
 			 state->patch.seq_offset, state->packet_duration,
-			 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+			 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+			 osmo_sockaddr_port(&addr->u.sa));
 		if (state->packet_duration == 0) {
 			state->packet_duration =
 			    rtp_end->codec->rate * 20 / 1000;
@@ -568,14 +596,16 @@
 				 "fixed packet duration is not available, "
 				 "using fixed 20ms instead: %d from %s:%d\n",
 				 state->packet_duration,
-				 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+				 osmo_sockaddr_port(&addr->u.sa));
 		}
 	} else if (state->in_stream.ssrc != ssrc) {
 		LOGPENDP(endp, DRTP, LOGL_NOTICE,
 			 "SSRC changed: %u -> %u  "
 			 "from %s:%d\n",
 			 state->in_stream.ssrc, rtp_hdr->ssrc,
-			 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+			 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+			 osmo_sockaddr_port(&addr->u.sa));
 
 		state->in_stream.ssrc = ssrc;
 		if (rtp_end->force_constant_ssrc) {
@@ -604,7 +634,8 @@
 				 "SeqNo offset: %d, TS offset: %d "
 				 "from %s:%d\n", state->in_stream.ssrc,
 				 state->patch.seq_offset, state->patch.timestamp_offset,
-				 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf),
+	 		 	 osmo_sockaddr_port(&addr->u.sa));
 		}
 
 		state->in_stream.last_tsdelta = 0;
@@ -825,7 +856,7 @@
  *  \param[in] conn_src associated source connection.
  *  \param[in] conn_dst associated destination connection.
  *  \returns 0 on success, -1 on ERROR. */
-int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,
+int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,
 	      struct msgb *msg, struct mgcp_conn_rtp *conn_src,
 	      struct mgcp_conn_rtp *conn_dst)
 {
@@ -836,6 +867,7 @@
 	struct mgcp_trunk *trunk = endp->trunk;
 	struct mgcp_rtp_end *rtp_end;
 	struct mgcp_rtp_state *rtp_state;
+	char ipbuf[INET6_ADDRSTRLEN];
 	char *dest_name;
 	int rc;
 	int len;
@@ -886,7 +918,7 @@
 			 "output disabled, drop to %s %s "
 			 "rtp_port:%u rtcp_port:%u\n",
 			 dest_name,
-			 inet_ntoa(rtp_end->addr),
+			 osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
 			 ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)
 		    );
 	} else if (is_rtp) {
@@ -932,7 +964,8 @@
 			LOGPENDP(endp, DRTP, LOGL_DEBUG,
 				 "process/send to %s %s "
 				 "rtp_port:%u rtcp_port:%u\n",
-				 dest_name, inet_ntoa(rtp_end->addr),
+				 dest_name,
+				 osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
 				 ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)
 				);
 
@@ -975,7 +1008,7 @@
 	} else if (!trunk->omit_rtcp) {
 		LOGPENDP(endp, DRTP, LOGL_DEBUG,
 			 "send to %s %s rtp_port:%u rtcp_port:%u\n",
-			 dest_name, inet_ntoa(rtp_end->addr),
+			 dest_name, osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),
 			 ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)
 			);
 
@@ -995,10 +1028,11 @@
 
 /* Check if the origin (addr) matches the address/port data of the RTP
  * connections. */
-static int check_rtp_origin(struct mgcp_conn_rtp *conn,
-			    struct sockaddr_in *addr)
+static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *addr)
 {
-	if (conn->end.addr.s_addr == 0) {
+	char ipbuf[INET6_ADDRSTRLEN];
+
+	if (addr_is_any(&conn->end.addr)) {
 		switch (conn->conn->mode) {
 		case MGCP_CONN_LOOPBACK:
 			/* HACK: for IuUP, we want to reply with an IuUP Initialization ACK upon the first RTP
@@ -1010,7 +1044,8 @@
 			 * MGCP port is in loopback mode, allow looping back the packet to any source. */
 			LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
 				 "In loopback mode and remote address not set:"
-				 " allowing data from address: %s\n", inet_ntoa(addr->sin_addr));
+				 " allowing data from address: %s\n",
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf));
 			return 0;
 
 		default:
@@ -1019,18 +1054,25 @@
 			 * confuse humans with expected errors. */
 			LOGPCONN(conn->conn, DRTP, LOGL_INFO,
 				 "Rx RTP from %s, but remote address not set:"
-				 " dropping early media\n", inet_ntoa(addr->sin_addr));
+				 " dropping early media\n",
+				 osmo_sockaddr_ntop(&addr->u.sa, ipbuf));
 			return -1;
 		}
 	}
 
 	/* Note: Check if the inbound RTP data comes from the same host to
 	 * which we send our outgoing RTP traffic. */
-	if (conn->end.addr.s_addr != addr->sin_addr.s_addr) {
+	if (conn->end.addr.u.sa.sa_family != addr->u.sa.sa_family ||
+	    (conn->end.addr.u.sa.sa_family == AF_INET &&
+	     conn->end.addr.u.sin.sin_addr.s_addr != addr->u.sin.sin_addr.s_addr) ||
+	    (conn->end.addr.u.sa.sa_family == AF_INET6 &&
+	     memcmp(&conn->end.addr.u.sin6.sin6_addr, &addr->u.sin6.sin6_addr,
+		    sizeof(struct in6_addr)) == 0)) {
 		LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
-			 "data from wrong address: %s, ", inet_ntoa(addr->sin_addr));
+			 "data from wrong address: %s, ",
+			 osmo_sockaddr_ntop(&addr->u.sa, ipbuf));
 		LOGPC(DRTP, LOGL_ERROR, "expected: %s\n",
-		      inet_ntoa(conn->end.addr));
+		      osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf));
 		LOGPCONN(conn->conn, DRTP, LOGL_ERROR, "packet tossed\n");
 		return -1;
 	}
@@ -1039,10 +1081,11 @@
 	 * the same as the remote port where we transmit outgoing RTP traffic
 	 * to (set by MDCX). We use this to check the origin of the data for
 	 * plausibility. */
-	if (conn->end.rtp_port != addr->sin_port &&
-	    conn->end.rtcp_port != addr->sin_port) {
+	if (conn->end.rtp_port != osmo_sockaddr_port(&addr->u.sa) &&
+	    conn->end.rtcp_port != osmo_sockaddr_port(&addr->u.sa)) {
 		LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
-			 "data from wrong source port: %d, ", ntohs(addr->sin_port));
+			 "data from wrong source port: %d, ",
+			 osmo_sockaddr_port(&addr->u.sa));
 		LOGPC(DRTP, LOGL_ERROR,
 		      "expected: %d for RTP or %d for RTCP\n",
 		      ntohs(conn->end.rtp_port), ntohs(conn->end.rtcp_port));
@@ -1057,26 +1100,29 @@
  * makes sense */
 static int check_rtp_destin(struct mgcp_conn_rtp *conn)
 {
+	char ipbuf[INET6_ADDRSTRLEN];
+	bool ip_is_any = addr_is_any(&conn->end.addr);
+
 	/* Note: it is legal to create a connection but never setting a port
 	 * and IP-address for outgoing data. */
-	if (strcmp(inet_ntoa(conn->end.addr), "0.0.0.0") == 0 && conn->end.rtp_port == 0) {
+	if (ip_is_any && conn->end.rtp_port == 0) {
 		LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,
 			 "destination IP-address and rtp port is (not yet) known (%s:%u)\n",
-			 inet_ntoa(conn->end.addr), conn->end.rtp_port);
+			 osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);
 		return -1;
 	}
 
-	if (strcmp(inet_ntoa(conn->end.addr), "0.0.0.0") == 0) {
+	if (ip_is_any) {
 		LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
 			 "destination IP-address is invalid (%s:%u)\n",
-			 inet_ntoa(conn->end.addr), conn->end.rtp_port);
+			 osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);
 		return -1;
 	}
 
 	if (conn->end.rtp_port == 0) {
 		LOGPCONN(conn->conn, DRTP, LOGL_ERROR,
 			 "destination rtp port is invalid (%s:%u)\n",
-			 inet_ntoa(conn->end.addr), conn->end.rtp_port);
+			 osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf), conn->end.rtp_port);
 		return -1;
 	}
 
@@ -1147,7 +1193,6 @@
 	struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
 	enum rtp_proto proto = mc->proto;
 	struct mgcp_conn_rtp *conn_src = mc->conn_src;
-	struct sockaddr_in *from_addr = mc->from_addr;
 	struct mgcp_endpoint *endp = conn_src->conn->endp;
 
 	LOGPENDP(endp, DRTP, LOGL_DEBUG, "destin conn:%s\n",
@@ -1167,7 +1212,7 @@
 			 "endpoint type is MGCP_RTP_DEFAULT, "
 			 "using mgcp_send() to forward data directly\n");
 		return mgcp_send(endp, proto == MGCP_PROTO_RTP,
-				 from_addr, msg, conn_src, conn_dst);
+				 mc->from_addr, msg, conn_src, conn_dst);
 	case MGCP_OSMUX_BSC_NAT:
 	case MGCP_OSMUX_BSC:
 		LOGPENDP(endp, DRTP, LOGL_DEBUG,
@@ -1197,7 +1242,7 @@
 	struct mgcp_conn_rtp *conn_src = mc->conn_src;
 	struct mgcp_conn *conn = conn_src->conn;
 	struct mgcp_conn *conn_dst;
-	struct sockaddr_in *from_addr = mc->from_addr;
+	struct osmo_sockaddr *from_addr = mc->from_addr;
 
 	/*! NOTE: This callback function implements the endpoint specific
 	 *  dispatch behaviour of an rtp bridge/proxy endpoint. It is assumed
@@ -1216,8 +1261,19 @@
 		 * address data from the UDP packet header to patch the
 		 * outgoing address in connection on the fly */
 		if (conn->u.rtp.end.rtp_port == 0) {
-			conn->u.rtp.end.addr = from_addr->sin_addr;
-			conn->u.rtp.end.rtp_port = from_addr->sin_port;
+			OSMO_ASSERT(conn->u.rtp.end.addr.u.sa.sa_family == from_addr->u.sa.sa_family);
+			switch (from_addr->u.sa.sa_family) {
+			case AF_INET:
+				conn->u.rtp.end.addr.u.sin.sin_addr = from_addr->u.sin.sin_addr;
+				conn->u.rtp.end.rtp_port = from_addr->u.sin.sin_port;
+				break;
+			case AF_INET6:
+				conn->u.rtp.end.addr.u.sin6.sin6_addr = from_addr->u.sin6.sin6_addr;
+				conn->u.rtp.end.rtp_port = from_addr->u.sin6.sin6_port;
+				break;
+			default:
+				OSMO_ASSERT(false);
+			}
 		}
 		return mgcp_send_rtp(conn_src, msg);
 	}
@@ -1266,7 +1322,7 @@
 	struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
 	struct mgcp_conn_rtp *conn_src = mc->conn_src;
 	struct mgcp_conn *conn = conn_src->conn;
-	struct sockaddr_in *from_addr = mc->from_addr;
+	struct osmo_sockaddr *from_addr = mc->from_addr;
 
 	/* Check if the connection is in loopback mode, if yes, just send the
 	 * incoming data back to the origin */
@@ -1276,8 +1332,19 @@
 		 * address data from the UDP packet header to patch the
 		 * outgoing address in connection on the fly */
 		if (conn->u.rtp.end.rtp_port == 0) {
-			conn->u.rtp.end.addr = from_addr->sin_addr;
-			conn->u.rtp.end.rtp_port = from_addr->sin_port;
+			OSMO_ASSERT(conn->u.rtp.end.addr.u.sa.sa_family == from_addr->u.sa.sa_family);
+			switch (from_addr->u.sa.sa_family) {
+			case AF_INET:
+				conn->u.rtp.end.addr.u.sin.sin_addr = from_addr->u.sin.sin_addr;
+				conn->u.rtp.end.rtp_port = from_addr->u.sin.sin_port;
+				break;
+			case AF_INET6:
+				conn->u.rtp.end.addr.u.sin6.sin6_addr = from_addr->u.sin6.sin6_addr;
+				conn->u.rtp.end.rtp_port = from_addr->u.sin6.sin6_port;
+				break;
+			default:
+				OSMO_ASSERT(false);
+			}
 		}
 		return mgcp_send_rtp(conn_src, msg);
 	}
@@ -1331,8 +1398,9 @@
 
 	struct mgcp_conn_rtp *conn_src;
 	struct mgcp_endpoint *endp;
-	struct sockaddr_in addr;
+	struct osmo_sockaddr addr;
 	socklen_t slen = sizeof(addr);
+	char ipbuf[INET6_ADDRSTRLEN];
 	int ret;
 	enum rtp_proto proto;
 	struct osmo_rtp_msg_ctx *mc;
@@ -1346,7 +1414,7 @@
 
 	proto = (fd == &conn_src->end.rtp)? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
 
-	ret = recvfrom(fd->fd, msgb_data(msg), msg->data_len, 0, (struct sockaddr *)&addr, &slen);
+	ret = recvfrom(fd->fd, msgb_data(msg), msg->data_len, 0, (struct sockaddr *)&addr.u.sa, &slen);
 
 	if (ret <= 0) {
 		LOG_CONN_RTP(conn_src, LOGL_ERROR, "recvfrom error: %s\n", strerror(errno));
@@ -1358,7 +1426,8 @@
 
 	LOG_CONN_RTP(conn_src, LOGL_DEBUG, "%s: rx %u bytes from %s:%u\n",
 		     proto == MGCP_PROTO_RTP ? "RTP" : "RTPC",
-		     msgb_length(msg), inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+		     msgb_length(msg), osmo_sockaddr_ntop(&addr.u.sa, ipbuf),
+		     osmo_sockaddr_port(&addr.u.sa));
 
 	if ((proto == MGCP_PROTO_RTP && check_rtp(conn_src, msg))
 	    || (proto == MGCP_PROTO_RTCP && check_rtcp(conn_src, msg))) {
@@ -1383,7 +1452,10 @@
 	};
 	LOG_CONN_RTP(conn_src, LOGL_DEBUG, "msg ctx: %d %p %s\n",
 		     mc->proto, mc->conn_src,
-		     osmo_hexdump((void*)mc->from_addr, sizeof(struct sockaddr_in)));
+		     osmo_hexdump((void*)mc->from_addr,
+				  mc->from_addr->u.sa.sa_family == AF_INET6 ?
+					sizeof(struct sockaddr_in6) :
+					sizeof(struct sockaddr_in)));
 
 	/* Increment RX statistics */
 	rate_ctr_inc(&conn_src->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR]);
@@ -1404,7 +1476,7 @@
 {
 	struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
 	struct mgcp_conn_rtp *conn_src = mc->conn_src;
-	struct sockaddr_in *from_addr = mc->from_addr;
+	struct osmo_sockaddr *from_addr = mc->from_addr;
 	struct mgcp_conn *conn = conn_src->conn;
 	struct mgcp_trunk *trunk = conn->endp->trunk;
 
@@ -1456,7 +1528,7 @@
 {
 	int rc;
 
-	rc = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, source_addr, port,
+	rc = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, source_addr, port,
 			     NULL, 0, OSMO_SOCK_F_BIND);
 	if (rc < 0) {
 		LOGP(DRTP, LOGL_ERROR, "failed to bind UDP port (%s:%i).\n",
@@ -1536,7 +1608,7 @@
 {
 	char name[512];
 	struct mgcp_rtp_end *end;
-	char local_ip_addr[INET_ADDRSTRLEN];
+	char local_ip_addr[INET6_ADDRSTRLEN];
 
 	snprintf(name, sizeof(name), "%s-%s", conn->conn->name, conn->conn->id);
 	end = &conn->end;
diff --git a/src/libosmo-mgcp/mgcp_osmux.c b/src/libosmo-mgcp/mgcp_osmux.c
index 93c922d..5864c95 100644
--- a/src/libosmo-mgcp/mgcp_osmux.c
+++ b/src/libosmo-mgcp/mgcp_osmux.c
@@ -148,15 +148,20 @@
 /* Lookup existing handle for a specified address, if the handle can not be
  * found, the function will automatically allocate one */
 static struct osmux_in_handle *
-osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
+osmux_handle_lookup(struct mgcp_config *cfg, struct osmo_sockaddr *addr, int rem_port)
 {
 	struct osmux_handle *h;
 
-	h = osmux_handle_find_get(addr, rem_port);
+	if (addr->u.sa.sa_family != AF_INET) {
+		LOGP(DLMGCP, LOGL_DEBUG, "IPv6 not supported in osmux yet!\n");
+		return NULL;
+	}
+
+	h = osmux_handle_find_get(&addr->u.sin.sin_addr, rem_port);
 	if (h != NULL)
 		return h->in;
 
-	h = osmux_handle_alloc(cfg, addr, rem_port);
+	h = osmux_handle_alloc(cfg, &addr->u.sin.sin_addr, rem_port);
 	if (h == NULL)
 		return NULL;
 
@@ -236,7 +241,7 @@
 {
 	struct mgcp_conn_rtp *conn = data;
 	struct mgcp_endpoint *endp = conn->conn->endp;
-	struct sockaddr_in addr = { /* FIXME: do we know the source address?? */ };
+	struct osmo_sockaddr addr = { /* FIXME: do we know the source address?? */ };
 	struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);
 	*mc = (struct osmo_rtp_msg_ctx){
 		.proto = MGCP_PROTO_RTP,
@@ -275,6 +280,8 @@
 static int endp_osmux_state_check(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
 				  bool sending)
 {
+	char ipbuf[INET6_ADDRSTRLEN];
+
 	switch(conn->osmux.state) {
 	case OSMUX_STATE_ACTIVATING:
 	if (osmux_enable_conn(endp, conn, &conn->end.addr, conn->end.rtp_port) < 0) {
@@ -287,7 +294,8 @@
 		LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,
 			 "Osmux %s CID %u towards %s:%u is now enabled\n",
 			 sending ? "sent" : "received",
-			 conn->osmux.cid, inet_ntoa(conn->end.addr),
+			 conn->osmux.cid,
+			 osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf),
 			 ntohs(conn->end.rtp_port));
 		return 0;
 	case OSMUX_STATE_ENABLED:
@@ -433,7 +441,7 @@
  *  \param[in] port portnumber of the remote OSMUX endpoint (in network byte order)
  *  \returns 0 on success, -1 on ERROR */
 int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
-		      struct in_addr *addr, uint16_t port)
+		      struct osmo_sockaddr *addr, uint16_t port)
 {
 	/*! If osmux is enabled, initialize the output handler. This handler is
 	 *  used to reconstruct the RTP flow from osmux. The RTP SSRC is
@@ -444,7 +452,7 @@
 	 *  overlapping RTP SSRC traveling to the BTSes behind the BSC,
 	 *  similarly, for flows traveling to the MSC.
 	 */
-	struct in_addr addr_unset = {};
+	struct in6_addr addr_unset = {};
 	static const uint32_t rtp_ssrc_winlen = UINT32_MAX / (OSMUX_CID_MAX + 1);
 	uint16_t osmux_dummy = endp->cfg->osmux_dummy;
 
@@ -457,7 +465,10 @@
 	}
 
 	/* Wait until we have the connection information from MDCX */
-	if (memcmp(&conn->end.addr, &addr_unset, sizeof(addr_unset)) == 0) {
+	if (memcmp(&conn->end.addr, &addr_unset,
+		   conn->end.addr.u.sa.sa_family == AF_INET6 ?
+			sizeof(struct in6_addr) :
+			sizeof(struct in_addr)) == 0) {
 		LOGPCONN(conn->conn, DLMGCP, LOGL_INFO,
 			"Osmux remote address/port still unknown\n");
 		return -1;
@@ -559,6 +570,7 @@
  *  \returns bytes sent, -1 on error */
 int osmux_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn)
 {
+	char ipbuf[INET6_ADDRSTRLEN];
 	struct osmux_hdr *osmuxh;
 	int buf_len;
 	struct in_addr addr_unset = {};
@@ -588,7 +600,8 @@
 
 	LOGPCONN(conn->conn, DLMGCP, LOGL_DEBUG,
 		 "sending OSMUX dummy load to %s:%u CID %u\n",
-		 inet_ntoa(conn->end.addr), ntohs(conn->end.rtp_port), conn->osmux.cid);
+		 osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf),
+		 ntohs(conn->end.rtp_port), conn->osmux.cid);
 
 	return mgcp_udp_send(osmux_fd.fd, &conn->end.addr,
 			     conn->end.rtp_port, (char*)osmuxh, buf_len);
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index 9ec4aee..1269524 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -230,7 +230,7 @@
 	struct msgb *sdp;
 	int rc;
 	struct msgb *result;
-	char local_ip_addr[INET_ADDRSTRLEN];
+	char local_ip_addr[INET6_ADDRSTRLEN];
 
 	sdp = msgb_alloc_headroom(4096, 128, "sdp record");
 	if (!sdp)
diff --git a/src/libosmo-mgcp/mgcp_sdp.c b/src/libosmo-mgcp/mgcp_sdp.c
index 1c3c89a..e98ca94 100644
--- a/src/libosmo-mgcp/mgcp_sdp.c
+++ b/src/libosmo-mgcp/mgcp_sdp.c
@@ -21,6 +21,9 @@
  */
 
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/core/sockaddr_str.h>
+
 #include <osmocom/mgcp/mgcp.h>
 #include <osmocom/mgcp/osmux.h>
 #include <osmocom/mgcp/mgcp_conn.h>
@@ -259,6 +262,42 @@
 	return -EINVAL;
 }
 
+
+static int audio_ip_from_sdp(struct osmo_sockaddr *dst_addr, char *sdp)
+{
+	bool is_ipv6;
+	char ipbuf[INET6_ADDRSTRLEN];
+	if (strncmp("c=IN IP", sdp, 7) != 0)
+		return -1;
+	sdp += 7;
+	if (*sdp == '6')
+	       is_ipv6 = true;
+	else if (*sdp == '4')
+	       is_ipv6 = false;
+	else
+	       return -1;
+	sdp++;
+	if (*sdp != ' ')
+		return -1;
+	sdp++;
+	if (is_ipv6) {
+		/* 45 = INET6_ADDRSTRLEN -1 */
+		if (sscanf(sdp, "%45s", ipbuf) != 1)
+			return -1;
+		if (inet_pton(AF_INET6, ipbuf, &dst_addr->u.sin6.sin6_addr) != 1)
+			return -1;
+		dst_addr->u.sa.sa_family = AF_INET6;
+	} else {
+		/* 15 = INET_ADDRSTRLEN -1 */
+		if (sscanf(sdp, "%15s", ipbuf) != 1)
+			return -1;
+		if (inet_pton(AF_INET, ipbuf, &dst_addr->u.sin.sin_addr) != 1)
+			return -1;
+		dst_addr->u.sa.sa_family = AF_INET;
+	}
+	return 0;
+}
+
 /* Pick optional fmtp parameters by payload type, if there are no fmtp
  * parameters, a nullpointer is returned */
 static struct mgcp_codec_param *param_by_pt(int pt, struct sdp_fmtp_param *fmtp_params, unsigned int fmtp_params_len)
@@ -289,6 +328,7 @@
 	struct sdp_fmtp_param fmtp_params[MGCP_MAX_CODECS];
 	unsigned int fmtp_used = 0;
 	struct mgcp_codec_param *codec_param;
+	char ipbuf[INET6_ADDRSTRLEN];
 	char *line;
 	unsigned int i;
 	void *tmp_ctx = talloc_new(NULL);
@@ -298,7 +338,6 @@
 	int ptime, ptime2 = 0;
 	char audio_name[64];
 	int port, rc;
-	char ipv4[16];
 
 	OSMO_ASSERT(endp);
 	OSMO_ASSERT(conn);
@@ -355,10 +394,8 @@
 				codecs_used = rc;
 			break;
 		case 'c':
-
-			if (sscanf(line, "c=IN IP4 %15s", ipv4) == 1) {
-				inet_aton(ipv4, &rtp->addr);
-			}
+			if (audio_ip_from_sdp(&rtp->addr, line) < 0)
+				return -1;
 			break;
 		default:
 			if (p->endp)
@@ -393,7 +430,7 @@
 
 	LOGPCONN(conn->conn, DLMGCP, LOGL_NOTICE,
 	     "Got media info via SDP: port:%d, addr:%s, duration:%d, payload-types:",
-	     ntohs(rtp->rtp_port), inet_ntoa(rtp->addr),
+	     ntohs(rtp->rtp_port), osmo_sockaddr_ntop(&rtp->addr.u.sa, ipbuf),
 	     rtp->packet_duration_ms);
 	if (codecs_used == 0)
 		LOGPC(DLMGCP, LOGL_NOTICE, "none");
@@ -529,6 +566,7 @@
 	int local_port;
 	struct sdp_fmtp_param fmtp_params[1];
         unsigned int fmtp_params_len = 0;
+	bool addr_is_v6;
 
 	OSMO_ASSERT(endp);
 	OSMO_ASSERT(conn);
@@ -543,12 +581,16 @@
 	audio_name = codec->audio_name;
 	payload_type = codec->payload_type;
 
+	addr_is_v6 = osmo_ip_str_type(addr) == AF_INET6;
+
 	rc = msgb_printf(sdp,
 			 "v=0\r\n"
-			 "o=- %s 23 IN IP4 %s\r\n"
+			 "o=- %s 23 IN IP%c %s\r\n"
 			 "s=-\r\n"
-			 "c=IN IP4 %s\r\n"
-			 "t=0 0\r\n", conn->conn->id, addr, addr);
+			 "c=IN IP%c %s\r\n"
+			 "t=0 0\r\n", conn->conn->id,
+			 addr_is_v6 ? '6' : '4', addr,
+			 addr_is_v6 ? '6' : '4', addr);
 
 	if (rc < 0)
 		goto buffer_too_small;
diff --git a/src/libosmo-mgcp/mgcp_vty.c b/src/libosmo-mgcp/mgcp_vty.c
index 22863c7..8ea1cdd 100644
--- a/src/libosmo-mgcp/mgcp_vty.c
+++ b/src/libosmo-mgcp/mgcp_vty.c
@@ -22,6 +22,7 @@
  */
 
 #include <osmocom/core/talloc.h>
+#include <osmocom/core/sockaddr_str.h>
 #include <osmocom/vty/misc.h>
 #include <osmocom/mgcp/mgcp.h>
 #include <osmocom/mgcp/mgcp_common.h>
@@ -407,9 +408,11 @@
 
 DEFUN(cfg_mgcp_local_ip,
       cfg_mgcp_local_ip_cmd,
-      "local ip A.B.C.D",
+      "local ip " VTY_IPV46_CMD,
       "Local options for the SDP record\n"
-      IP_STR "IPv4 Address to use in SDP record\n")
+      IP_STR
+      "IPv4 Address to use in SDP record\n"
+      "IPv6 Address to use in SDP record\n")
 {
 	osmo_talloc_replace_string(g_cfg, &g_cfg->local_ip, argv[0]);
 	return CMD_SUCCESS;
@@ -418,7 +421,10 @@
 #define BIND_STR "Listen/Bind related socket option\n"
 DEFUN(cfg_mgcp_bind_ip,
       cfg_mgcp_bind_ip_cmd,
-      "bind ip A.B.C.D", BIND_STR IP_STR "IPv4 Address to bind to\n")
+      "bind ip " VTY_IPV46_CMD,
+      BIND_STR IP_STR
+      "IPv4 Address to bind to\n"
+      "IPv6 Address to bind to\n")
 {
 	osmo_talloc_replace_string(g_cfg, &g_cfg->source_addr, argv[0]);
 	return CMD_SUCCESS;
@@ -494,8 +500,10 @@
 
 DEFUN(cfg_mgcp_rtp_bind_ip,
       cfg_mgcp_rtp_bind_ip_cmd,
-      "rtp bind-ip A.B.C.D",
-      RTP_STR "Bind endpoints facing the Network\n" "Address to bind to\n")
+      "rtp bind-ip " VTY_IPV46_CMD,
+      RTP_STR "Bind endpoints facing the Network\n"
+      "IPv4 Address to bind to\n"
+      "IPv6 Address to bind to\n")
 {
 	osmo_talloc_replace_string(g_cfg, &g_cfg->net_ports.bind_addr, argv[0]);
 	return CMD_SUCCESS;
@@ -850,11 +858,13 @@
 	return CMD_SUCCESS;
 }
 
-#define CALL_AGENT_STR "Callagent information\n"
+#define CALL_AGENT_STR "Call agent information\n"
 DEFUN(cfg_mgcp_agent_addr,
       cfg_mgcp_agent_addr_cmd,
-      "call-agent ip A.B.C.D",
-      CALL_AGENT_STR IP_STR "IPv4 Address of the callagent\n")
+      "call-agent ip " VTY_IPV46_CMD,
+      CALL_AGENT_STR IP_STR
+      "IPv4 Address of the call agent\n"
+      "IPv6 Address of the call agent\n")
 {
 	osmo_talloc_replace_string(g_cfg, &g_cfg->call_agent_addr, argv[0]);
 	return CMD_SUCCESS;
@@ -1236,13 +1246,15 @@
 
 DEFUN(tap_rtp,
       tap_rtp_cmd,
-      "tap-rtp <0-64> ENDPOINT CONN (in|out) A.B.C.D <0-65534>",
+      "tap-rtp <0-64> ENDPOINT CONN (in|out) " VTY_IPV46_CMD " <0-65534>",
       "Forward data on endpoint to a different system\n" "Trunk number\n"
       "The endpoint in hex\n"
       "The connection id in hex\n"
       "Forward incoming data\n"
       "Forward leaving data\n"
-      "destination IP of the data\n" "destination port\n")
+      "Destination IPv4 of the data\n"
+      "Destination IPv6 of the data\n"
+      "Destination port\n")
 {
 	struct mgcp_rtp_tap *tap;
 	struct mgcp_trunk *trunk;
@@ -1290,8 +1302,22 @@
 	}
 
 	memset(&tap->forward, 0, sizeof(tap->forward));
-	inet_aton(argv[4], &tap->forward.sin_addr);
-	tap->forward.sin_port = htons(atoi(argv[5]));
+
+	tap->forward.u.sa.sa_family = osmo_ip_str_type(argv[4]);
+	switch (tap->forward.u.sa.sa_family) {
+	case AF_INET:
+		if (inet_pton(AF_INET, argv[4], &tap->forward.u.sin.sin_addr) != 1)
+			return CMD_WARNING;
+		tap->forward.u.sin.sin_port = htons(atoi(argv[5]));
+		break;
+	case AF_INET6:
+		if (inet_pton(AF_INET6, argv[4], &tap->forward.u.sin6.sin6_addr) != 1)
+			return CMD_WARNING;
+		tap->forward.u.sin6.sin6_port = htons(atoi(argv[5]));
+		break;
+	default:
+		return CMD_WARNING;
+	}
 	tap->enabled = 1;
 	return CMD_SUCCESS;
 }
@@ -1407,7 +1433,10 @@
 
 DEFUN(cfg_mgcp_osmux_ip,
       cfg_mgcp_osmux_ip_cmd,
-      "osmux bind-ip A.B.C.D", OSMUX_STR IP_STR "IPv4 Address to bind to\n")
+      "osmux bind-ip " VTY_IPV46_CMD,
+      OSMUX_STR IP_STR
+      "IPv4 Address to bind to\n"
+      "IPv6 Address to bind to\n")
 {
 	osmo_talloc_replace_string(g_cfg, &g_cfg->osmux_addr, argv[0]);
 	return CMD_SUCCESS;
diff --git a/src/osmo-mgw/mgw_main.c b/src/osmo-mgw/mgw_main.c
index 7f4df2e..37357a0 100644
--- a/src/osmo-mgw/mgw_main.c
+++ b/src/osmo-mgw/mgw_main.c
@@ -179,7 +179,7 @@
 
 static int read_call_agent(struct osmo_fd *fd, unsigned int what)
 {
-	struct sockaddr_in addr;
+	struct osmo_sockaddr addr;
 	socklen_t slen = sizeof(addr);
 	struct msgb *msg;
 	struct msgb *resp;
@@ -205,7 +205,7 @@
 	msgb_reset(msg);
 
 	if (resp) {
-		sendto(cfg->gw_fd.bfd.fd, resp->l2h, msgb_l2len(resp), 0, (struct sockaddr *) &addr, sizeof(addr));
+		sendto(cfg->gw_fd.bfd.fd, resp->l2h, msgb_l2len(resp), 0, &addr.u.sa, sizeof(addr));
 		msgb_free(resp);
 	}
 
@@ -345,7 +345,7 @@
 	if (cfg->call_agent_addr)
 		flags |= OSMO_SOCK_F_CONNECT;
 
-	rc = osmo_sock_init2_ofd(&cfg->gw_fd.bfd, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
+	rc = osmo_sock_init2_ofd(&cfg->gw_fd.bfd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
 				cfg->source_addr, cfg->source_port,
 				cfg->call_agent_addr, cfg->call_agent_addr ? 2727 : 0, flags);
 	if (rc < 0) {
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c
index c5b6d17..620b0d1 100644
--- a/tests/mgcp/mgcp_test.c
+++ b/tests/mgcp/mgcp_test.c
@@ -34,6 +34,7 @@
 #include <osmocom/core/application.h>
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/utils.h>
+#include <osmocom/core/socket.h>
 #include <string.h>
 #include <limits.h>
 #include <dlfcn.h>
@@ -1262,7 +1263,7 @@
 void mgcp_patch_and_count(struct mgcp_endpoint *endp,
 			  struct mgcp_rtp_state *state,
 			  struct mgcp_rtp_end *rtp_end,
-			  struct sockaddr_in *addr, struct msgb *msg);
+			  struct osmo_sockaddr *addr, struct msgb *msg);
 
 static void test_packet_error_detection(int patch_ssrc, int patch_ts)
 {
@@ -1274,7 +1275,7 @@
 	struct mgcp_config cfg = {0};
 	struct mgcp_rtp_state state;
 	struct mgcp_rtp_end *rtp;
-	struct sockaddr_in addr = { 0 };
+	struct osmo_sockaddr addr = { 0 };
 	uint32_t last_ssrc = 0;
 	uint32_t last_timestamp = 0;
 	uint32_t last_seqno = 0;
@@ -1486,7 +1487,8 @@
 	OSMO_ASSERT(conn->end.rtp_port == htons(16434));
 	memset(&addr, 0, sizeof(addr));
 	inet_aton("8.8.8.8", &addr);
-	OSMO_ASSERT(conn->end.addr.s_addr == addr.s_addr);
+	OSMO_ASSERT(conn->end.addr.u.sa.sa_family == AF_INET);
+	OSMO_ASSERT(conn->end.addr.u.sin.sin_addr.s_addr == addr.s_addr);
 
 	/* Check what happens without that flag */
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-mgw/+/19969
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Change-Id: I504ca776d88fd852bbaef07060c125980db3fdd7
Gerrit-Change-Number: 19969
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200903/e23424a5/attachment.htm>


More information about the gerrit-log mailing list