mgcp: Allocate a different port for the networking...

Use the right source port when sending the message.
diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index 811ba2c..9d0c60f 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -29,6 +29,7 @@
 #include <arpa/inet.h>
 
 #define RTP_PORT_DEFAULT 4000
+#define RTP_PORT_NET_DEFAULT 16000
 
 /**
  * Calculate the RTP audio port for the given multiplex
@@ -92,6 +93,7 @@
 	int audio_payload;
 	int audio_loop;
 	int rtp_bts_base_port;
+	int rtp_net_base_port;
 	int endp_dscp;
 
 	/* spec handling */
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 357f3bf..6c23673 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -99,5 +99,6 @@
 			const char **transaction_id, struct mgcp_endpoint **endp);
 int mgcp_send_dummy(struct mgcp_endpoint *endp);
 int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
+int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
 
 #endif
diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c
index 94f88b9..0f0f222 100644
--- a/openbsc/src/mgcp/mgcp_network.c
+++ b/openbsc/src/mgcp/mgcp_network.c
@@ -236,21 +236,27 @@
 		dest = !dest;
 
 	if (dest == DEST_NETWORK) {
-		if (proto == PROTO_RTP)
+		if (proto == PROTO_RTP) {
 			patch_and_count(endp, &endp->bts_state,
 					endp->net_end.payload_type,
 					&addr, buf, rc);
-		return udp_send(fd->fd, &endp->net_end.addr,
-			     proto == PROTO_RTP ? endp->net_end.rtp_port : endp->net_end.rtcp_port,
-			     buf, rc);
+			return udp_send(endp->net_end.rtp.fd, &endp->net_end.addr,
+					endp->net_end.rtp_port, buf, rc);
+		} else {
+			return udp_send(endp->net_end.rtcp.fd, &endp->net_end.addr,
+					endp->net_end.rtcp_port, buf, rc);
+		}
 	} else {
-		if (proto == PROTO_RTP)
+		if (proto == PROTO_RTP) {
 			patch_and_count(endp, &endp->net_state,
 					endp->bts_end.payload_type,
 					&addr, buf, rc);
-		return udp_send(fd->fd, &endp->bts_end.addr,
-			     proto == PROTO_RTP ? endp->bts_end.rtp_port : endp->bts_end.rtcp_port,
-			     buf, rc);
+			return udp_send(endp->bts_end.rtp.fd, &endp->bts_end.addr,
+					endp->bts_end.rtp_port, buf, rc);
+		} else {
+			return udp_send(endp->bts_end.rtcp.fd, &endp->bts_end.addr,
+					endp->bts_end.rtcp_port, buf, rc);
+		}
 	}
 }
 
@@ -286,53 +292,47 @@
 	return ret != 0;
 }
 
-static int bind_rtp(struct mgcp_endpoint *endp)
+static int bind_rtp(struct mgcp_config *cfg, struct mgcp_rtp_end *rtp_end, int endpno)
 {
-	struct mgcp_config *cfg = endp->cfg;
-
-	if (create_bind(cfg->source_addr, &endp->bts_end.rtp, endp->bts_end.local_port) != 0) {
+	if (create_bind(cfg->source_addr, &rtp_end->rtp, rtp_end->local_port) != 0) {
 		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
-		       cfg->source_addr, endp->bts_end.local_port, ENDPOINT_NUMBER(endp));
+		       cfg->source_addr, rtp_end->local_port, endpno);
 		goto cleanup0;
 	}
 
-	if (create_bind(cfg->source_addr, &endp->bts_end.rtcp, endp->bts_end.local_port + 1) != 0) {
+	if (create_bind(cfg->source_addr, &rtp_end->rtcp, rtp_end->local_port + 1) != 0) {
 		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
-		       cfg->source_addr, endp->bts_end.local_port + 1, ENDPOINT_NUMBER(endp));
+		       cfg->source_addr, rtp_end->local_port + 1, endpno);
 		goto cleanup1;
 	}
 
-	set_ip_tos(endp->bts_end.rtp.fd, cfg->endp_dscp);
-	set_ip_tos(endp->bts_end.rtcp.fd, cfg->endp_dscp);
+	set_ip_tos(rtp_end->rtp.fd, cfg->endp_dscp);
+	set_ip_tos(rtp_end->rtcp.fd, cfg->endp_dscp);
 
-	endp->bts_end.rtp.cb = rtp_data_cb;
-	endp->bts_end.rtp.data = endp;
-	endp->bts_end.rtp.when = BSC_FD_READ;
-	if (bsc_register_fd(&endp->bts_end.rtp) != 0) {
+	rtp_end->rtp.when = BSC_FD_READ;
+	if (bsc_register_fd(&rtp_end->rtp) != 0) {
 		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTP port %d on 0x%x\n",
-			endp->bts_end.local_port, ENDPOINT_NUMBER(endp));
+			rtp_end->local_port, endpno);
 		goto cleanup2;
 	}
 
-	endp->bts_end.rtcp.cb = rtp_data_cb;
-	endp->bts_end.rtcp.data = endp;
-	endp->bts_end.rtcp.when = BSC_FD_READ;
-	if (bsc_register_fd(&endp->bts_end.rtcp) != 0) {
+	rtp_end->rtcp.when = BSC_FD_READ;
+	if (bsc_register_fd(&rtp_end->rtcp) != 0) {
 		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTCP port %d on 0x%x\n",
-			endp->bts_end.local_port + 1, ENDPOINT_NUMBER(endp));
+			rtp_end->local_port + 1, endpno);
 		goto cleanup3;
 	}
 
 	return 0;
 
 cleanup3:
-	bsc_unregister_fd(&endp->bts_end.rtp);
+	bsc_unregister_fd(&rtp_end->rtp);
 cleanup2:
-	close(endp->bts_end.rtcp.fd);
-	endp->bts_end.rtcp.fd = -1;
+	close(rtp_end->rtcp.fd);
+	rtp_end->rtcp.fd = -1;
 cleanup1:
-	close(endp->bts_end.rtp.fd);
-	endp->bts_end.rtp.fd = -1;
+	close(rtp_end->rtp.fd);
+	rtp_end->rtp.fd = -1;
 cleanup0:
 	return -1;
 }
@@ -340,5 +340,19 @@
 int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
 {
 	endp->bts_end.local_port = rtp_port;
-	return bind_rtp(endp);
+	endp->bts_end.rtp.cb = rtp_data_cb;
+	endp->bts_end.rtp.data = endp;
+	endp->bts_end.rtcp.data = endp;
+	endp->bts_end.rtcp.cb = rtp_data_cb;
+	return bind_rtp(endp->cfg, &endp->bts_end, ENDPOINT_NUMBER(endp));
+}
+
+int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
+{
+	endp->net_end.local_port = rtp_port;
+	endp->net_end.rtp.cb = rtp_data_cb;
+	endp->net_end.rtp.data = endp;
+	endp->net_end.rtcp.data = endp;
+	endp->net_end.rtcp.cb = rtp_data_cb;
+	return bind_rtp(endp->cfg, &endp->net_end, ENDPOINT_NUMBER(endp));
 }
diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c
index 8dbe2b0..211ec3e 100644
--- a/openbsc/src/mgcp/mgcp_protocol.c
+++ b/openbsc/src/mgcp/mgcp_protocol.c
@@ -429,6 +429,8 @@
 	/* bind to the port now */
 	port = rtp_calculate_port(ENDPOINT_NUMBER(endp), cfg->rtp_bts_base_port);
 	endp->bts_end.local_port = port;
+
+	port = rtp_calculate_port(ENDPOINT_NUMBER(endp), cfg->rtp_net_base_port);
 	endp->net_end.local_port = port;
 
 	/* assign a local call identifier or fail */
@@ -709,6 +711,7 @@
 	cfg->audio_name = talloc_strdup(cfg, "GSM-EFR/8000");
 	cfg->audio_payload = 97;
 	cfg->rtp_bts_base_port = RTP_PORT_DEFAULT;
+	cfg->rtp_net_base_port = RTP_PORT_NET_DEFAULT;
 
 	return cfg;
 }
diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c
index ea10a2e..fe73c7a 100644
--- a/openbsc/src/mgcp/mgcp_vty.c
+++ b/openbsc/src/mgcp/mgcp_vty.c
@@ -57,6 +57,7 @@
 	vty_out(vty, "  bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE);
 	vty_out(vty, "  bind port %u%s", g_cfg->source_port, VTY_NEWLINE);
 	vty_out(vty, "  rtp bts-base %u%s", g_cfg->rtp_bts_base_port, VTY_NEWLINE);
+	vty_out(vty, "  rtp net-base %u%s", g_cfg->rtp_net_base_port, VTY_NEWLINE);
 	vty_out(vty, "  rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
 	if (g_cfg->audio_payload != -1)
 		vty_out(vty, "  sdp audio payload number %d%s", g_cfg->audio_payload, VTY_NEWLINE);
@@ -163,6 +164,16 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_mgcp_rtp_net_base_port,
+      cfg_mgcp_rtp_net_base_port_cmd,
+      "rtp net-base <0-65534>",
+      "Base port to use for network port\n" "Port\n")
+{
+	unsigned int port = atoi(argv[0]);
+	g_cfg->rtp_net_base_port = port;
+	return CMD_SUCCESS;
+}
+
 ALIAS_DEPRECATED(cfg_mgcp_rtp_bts_base_port, cfg_mgcp_rtp_base_port_cmd,
       "rtp base <0-65534>", "Base port to use")
 
@@ -277,6 +288,7 @@
 	install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_bts_base_port_cmd);
+	install_element(MGCP_NODE, &cfg_mgcp_rtp_net_base_port_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
@@ -322,6 +334,12 @@
 			LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
 			return -1;
 		}
+
+		rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp), g_cfg->rtp_net_base_port);
+		if (mgcp_bind_net_rtp_port(endp, rtp_port) != 0) {
+			LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
+			return -1;
+		}
 	}
 
 	return 0;