Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02dea65c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: Add support for UL Firewall"

parents c1410196 50d04e6b
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -86,7 +86,9 @@ const char *ipa_event_name[] = {
	__stringify(ADD_VLAN_IFACE),
	__stringify(DEL_VLAN_IFACE),
	__stringify(ADD_L2TP_VLAN_MAPPING),
	__stringify(DEL_L2TP_VLAN_MAPPING)
	__stringify(DEL_L2TP_VLAN_MAPPING),
	__stringify(IPA_PER_CLIENT_STATS_CONNECT_EVENT),
	__stringify(IPA_PER_CLIENT_STATS_DISCONNECT_EVENT),
};

const char *ipa_hdr_l2_type_name[] = {
+43 −0
Original line number Diff line number Diff line
@@ -1016,6 +1016,49 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			break;
		}
		break;

	case IPA_IOC_ADD_RT_RULE_EXT:
		if (copy_from_user(header,
				(const void __user *)arg,
				sizeof(struct ipa_ioc_add_rt_rule_ext))) {
			retval = -EFAULT;
			break;
		}
		pre_entry =
			((struct ipa_ioc_add_rt_rule_ext *)header)->num_rules;
		pyld_sz =
		   sizeof(struct ipa_ioc_add_rt_rule_ext) +
		   pre_entry * sizeof(struct ipa_rt_rule_add_ext);
		param = kzalloc(pyld_sz, GFP_KERNEL);
		if (!param) {
			retval = -ENOMEM;
			break;
		}
		if (copy_from_user(param, (const void __user *)arg, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		/* add check in case user-space module compromised */
		if (unlikely(
			((struct ipa_ioc_add_rt_rule_ext *)param)->num_rules
			!= pre_entry)) {
			IPAERR(" prevent memory corruption(%d not match %d)\n",
				((struct ipa_ioc_add_rt_rule_ext *)param)->
				num_rules,
				pre_entry);
			retval = -EINVAL;
			break;
		}
		if (ipa3_add_rt_rule_ext(
			(struct ipa_ioc_add_rt_rule_ext *)param)) {
			retval = -EFAULT;
			break;
		}
		if (copy_to_user((void __user *)arg, param, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		break;
	case IPA_IOC_ADD_RT_RULE_AFTER:
		if (copy_from_user(header, (const void __user *)arg,
			sizeof(struct ipa_ioc_add_rt_rule_after))) {
+3 −1
Original line number Diff line number Diff line
@@ -70,7 +70,9 @@ const char *ipa3_event_name[] = {
	__stringify(ADD_VLAN_IFACE),
	__stringify(DEL_VLAN_IFACE),
	__stringify(ADD_L2TP_VLAN_MAPPING),
	__stringify(DEL_L2TP_VLAN_MAPPING)
	__stringify(DEL_L2TP_VLAN_MAPPING),
	__stringify(IPA_PER_CLIENT_STATS_CONNECT_EVENT),
	__stringify(IPA_PER_CLIENT_STATS_DISCONNECT_EVENT),
};

const char *ipa3_hdr_l2_type_name[] = {
+3 −0
Original line number Diff line number Diff line
@@ -433,6 +433,7 @@ struct ipa3_rt_entry {
	int id;
	u16 prio;
	u16 rule_id;
	u16 rule_id_valid;
};

/**
@@ -1760,6 +1761,8 @@ int ipa3_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls,
 */
int ipa3_add_rt_rule(struct ipa_ioc_add_rt_rule *rules);

int ipa3_add_rt_rule_ext(struct ipa_ioc_add_rt_rule_ext *rules);

int ipa3_add_rt_rule_after(struct ipa_ioc_add_rt_rule_after *rules);

int ipa3_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls);
+150 −0
Original line number Diff line number Diff line
@@ -758,6 +758,57 @@ int ipa3_qmi_filter_request_ex_send(
		resp.resp.error, "ipa_install_filter");
}

/* sending ul-filter-install-request to modem*/
int ipa3_qmi_ul_filter_request_send(
	struct ipa_configure_ul_firewall_rules_req_msg_v01 *req)
{
	struct ipa_configure_ul_firewall_rules_resp_msg_v01 resp;
	struct msg_desc req_desc, resp_desc;
	int rc;

	IPAWANDBG("IPACM pass %u rules to Q6\n",
		req->firewall_rules_list_len);

	mutex_lock(&ipa3_qmi_lock);
	if (ipa3_qmi_ctx != NULL) {
		/* cache the qmi_filter_request */
		memcpy(
		&(ipa3_qmi_ctx->ipa_configure_ul_firewall_rules_req_msg_cache[
		ipa3_qmi_ctx->num_ipa_configure_ul_firewall_rules_req_msg]),
		req,
		sizeof(struct
		ipa_configure_ul_firewall_rules_req_msg_v01));
		ipa3_qmi_ctx->num_ipa_configure_ul_firewall_rules_req_msg++;
		ipa3_qmi_ctx->num_ipa_configure_ul_firewall_rules_req_msg %=
			MAX_NUM_QMI_RULE_CACHE;
	}
	mutex_unlock(&ipa3_qmi_lock);

	req_desc.max_msg_len =
		QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_MAX_MSG_LEN_V01;
	req_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01;
	req_desc.ei_array =
		ipa3_configure_ul_firewall_rules_req_msg_data_v01_ei;

	memset(&resp, 0,
		sizeof(struct ipa_configure_ul_firewall_rules_resp_msg_v01));
	resp_desc.max_msg_len =
		QMI_IPA_INSTALL_UL_FIREWALL_RULES_RESP_MAX_MSG_LEN_V01;
	resp_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_RESP_V01;
	resp_desc.ei_array =
		ipa3_configure_ul_firewall_rules_resp_msg_data_v01_ei;

	rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc,
		req,
		sizeof(
		struct ipa_configure_ul_firewall_rules_req_msg_v01),
		&resp_desc, &resp, sizeof(resp),
		QMI_SEND_REQ_TIMEOUT_MS);
	return ipa3_check_qmi_response(rc,
		QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01, resp.resp.result,
		resp.resp.error, "ipa_received_ul_firewall_filter");
}

int ipa3_qmi_enable_force_clear_datapath_send(
	struct ipa_enable_force_clear_datapath_req_msg_v01 *req)
{
@@ -967,6 +1018,7 @@ static void ipa3_q6_clnt_ind_cb(struct qmi_handle *handle, unsigned int msg_id,
			       void *ind_cb_priv)
{
	struct ipa_data_usage_quota_reached_ind_msg_v01 qmi_ind;
	struct ipa_configure_ul_firewall_rules_ind_msg_v01 qmi_ul_firewall_ind;
	struct msg_desc qmi_ind_desc;
	int rc = 0;

@@ -995,6 +1047,36 @@ static void ipa3_q6_clnt_ind_cb(struct qmi_handle *handle, unsigned int msg_id,
		ipa3_broadcast_quota_reach_ind(qmi_ind.apn.mux_id,
			IPA_UPSTEAM_MODEM);
	}

	if (msg_id == QMI_IPA_INSTALL_UL_FIREWALL_RULES_IND_V01) {
		memset(&qmi_ul_firewall_ind, 0, sizeof(
			struct ipa_configure_ul_firewall_rules_ind_msg_v01));
		qmi_ind_desc.max_msg_len =
			QMI_IPA_INSTALL_UL_FIREWALL_RULES_IND_MAX_MSG_LEN_V01;
		qmi_ind_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_IND_V01;
		qmi_ind_desc.ei_array =
			ipa3_configure_ul_firewall_rules_ind_msg_data_v01_ei;

		rc = qmi_kernel_decode(
			&qmi_ind_desc, &qmi_ul_firewall_ind, msg, msg_len);
		if (rc < 0) {
			IPAWANERR("Error decoding msg_id %d\n", msg_id);
			return;
		}

		IPAWANDBG("UL firewall rules install indication on Q6");
		if (qmi_ul_firewall_ind.result.is_success ==
				QMI_IPA_UL_FIREWALL_STATUS_SUCCESS_V01) {
			IPAWANDBG(" : Success\n");
			IPAWANDBG
			("Mux ID : %d\n", qmi_ul_firewall_ind.result.mux_id);
		} else if (qmi_ul_firewall_ind.result.is_success ==
				QMI_IPA_UL_FIREWALL_STATUS_FAILURE_V01){
			IPAWANERR(": Failure\n");
		} else {
			IPAWANERR(": Unexpected Result");
		}
	}
}

static void ipa3_q6_clnt_svc_arrive(struct work_struct *work)
@@ -1446,6 +1528,74 @@ int ipa3_qmi_stop_data_qouta(void)
		resp.resp.error, "ipa_stop_data_usage_quota_req_msg_v01");
}

int ipa3_qmi_enable_per_client_stats(
	struct ipa_enable_per_client_stats_req_msg_v01 *req,
	struct ipa_enable_per_client_stats_resp_msg_v01 *resp)
{
	struct msg_desc req_desc, resp_desc;
	int rc;

	req_desc.max_msg_len =
		QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_MAX_MSG_LEN_V01;
	req_desc.msg_id =
		QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01;
	req_desc.ei_array =
		ipa3_enable_per_client_stats_req_msg_data_v01_ei;

	resp_desc.max_msg_len =
		QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_MAX_MSG_LEN_V01;
	resp_desc.msg_id =
		QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_V01;
	resp_desc.ei_array =
		ipa3_enable_per_client_stats_resp_msg_data_v01_ei;

	IPAWANDBG("Sending QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01\n");

	rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req,
		sizeof(struct ipa_enable_per_client_stats_req_msg_v01),
		&resp_desc, resp,
		sizeof(struct ipa_enable_per_client_stats_resp_msg_v01),
		QMI_SEND_STATS_REQ_TIMEOUT_MS);

	IPAWANDBG("QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_V01 received\n");

	return ipa3_check_qmi_response(rc,
		QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01, resp->resp.result,
		resp->resp.error, "ipa3_qmi_enable_per_client_stats");
}

int ipa3_qmi_get_per_client_packet_stats(
	struct ipa_get_stats_per_client_req_msg_v01 *req,
	struct ipa_get_stats_per_client_resp_msg_v01 *resp)
{
	struct msg_desc req_desc, resp_desc;
	int rc;

	req_desc.max_msg_len = QMI_IPA_GET_STATS_PER_CLIENT_REQ_MAX_MSG_LEN_V01;
	req_desc.msg_id = QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01;
	req_desc.ei_array = ipa3_get_stats_per_client_req_msg_data_v01_ei;

	resp_desc.max_msg_len =
		QMI_IPA_GET_STATS_PER_CLIENT_RESP_MAX_MSG_LEN_V01;
	resp_desc.msg_id = QMI_IPA_GET_STATS_PER_CLIENT_RESP_V01;
	resp_desc.ei_array = ipa3_get_stats_per_client_resp_msg_data_v01_ei;

	IPAWANDBG("Sending QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01\n");

	rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req,
			sizeof(struct ipa_get_stats_per_client_req_msg_v01),
			&resp_desc, resp,
			sizeof(struct ipa_get_stats_per_client_resp_msg_v01),
			QMI_SEND_STATS_REQ_TIMEOUT_MS);

	IPAWANDBG("QMI_IPA_GET_STATS_PER_CLIENT_RESP_V01 received\n");

	return ipa3_check_qmi_response(rc,
		QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01, resp->resp.result,
		resp->resp.error,
		"struct ipa_get_stats_per_client_req_msg_v01");
}

void ipa3_qmi_init(void)
{
	mutex_init(&ipa3_qmi_lock);
Loading