aboutsummaryrefslogtreecommitdiff
path: root/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp
diff options
context:
space:
mode:
authorLouis Popi <theh2o64@gmail.com>2016-05-06 10:13:04 +0200
committerdavidevinavil <davidevinavil@gmail.com>2017-01-21 18:19:27 +0100
commit11e7b3c6aa71b15800f7cf989ac71bbd85a68e51 (patch)
tree67eadbdd23c445f3650bd45773800ae5c917e9d8 /data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp
parent5b17622206a2697dfe6e6a31a21e427fc85ab8ee (diff)
z2_plus: Import data-ipa-cfg-mgr from CAF
Change-Id: I6f134eb024b8b5be7ae119005cbc471d583ee8a6
Diffstat (limited to 'data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp')
-rw-r--r--data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp
new file mode 100644
index 0000000..7ae6131
--- /dev/null
+++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp
@@ -0,0 +1,274 @@
+/*
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*!
+ @file
+ IPACM_Routing.cpp
+
+ @brief
+ This file implements the IPACM routing functionality.
+
+ @Author
+
+*/
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "IPACM_Routing.h"
+#include <IPACM_Log.h>
+
+const char *IPACM_Routing::DEVICE_NAME = "/dev/ipa";
+
+IPACM_Routing::IPACM_Routing()
+{
+ m_fd = open(DEVICE_NAME, O_RDWR);
+ if (0 == m_fd)
+ {
+ IPACMERR("Failed opening %s.\n", DEVICE_NAME);
+ }
+}
+
+IPACM_Routing::~IPACM_Routing()
+{
+ close(m_fd);
+}
+
+bool IPACM_Routing::DeviceNodeIsOpened()
+{
+ int res = fcntl(m_fd, F_GETFL);
+
+ if (m_fd > 0 && res >= 0) return true;
+ else return false;
+
+}
+
+bool IPACM_Routing::AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable)
+{
+ int retval = 0, cnt=0;
+ bool isInvalid = false;
+
+ if (!DeviceNodeIsOpened())
+ {
+ IPACMERR("Device is not opened\n");
+ return false;
+ }
+
+ for(cnt=0; cnt<ruleTable->num_rules; cnt++)
+ {
+ if(ruleTable->rules[cnt].rule.dst > IPA_CLIENT_MAX)
+ {
+ IPACMERR("Invalid dst pipe, Rule:%d dst_pipe:%d\n", cnt, ruleTable->rules[cnt].rule.dst);
+ isInvalid = true;
+ }
+ }
+
+ if(isInvalid)
+ {
+ return false;
+ }
+
+ retval = ioctl(m_fd, IPA_IOC_ADD_RT_RULE, ruleTable);
+ if (retval)
+ {
+ IPACMERR("Failed adding routing rule %p\n", ruleTable);
+ return false;
+ }
+
+ for(cnt=0; cnt<ruleTable->num_rules; cnt++)
+ {
+ IPACMDBG("Rule:%d dst_pipe:%d\n", cnt, ruleTable->rules[cnt].rule.dst);
+ }
+
+ IPACMDBG_H("Added routing rule %p\n", ruleTable);
+ return true;
+}
+
+bool IPACM_Routing::DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable)
+{
+ int retval = 0;
+
+ if (!DeviceNodeIsOpened()) return false;
+
+ retval = ioctl(m_fd, IPA_IOC_DEL_RT_RULE, ruleTable);
+ if (retval)
+ {
+ IPACMERR("Failed deleting routing rule table %p\n", ruleTable);
+ return false;
+ }
+
+ IPACMDBG_H("Deleted routing rule %p\n", ruleTable);
+ return true;
+}
+
+bool IPACM_Routing::Commit(enum ipa_ip_type ip)
+{
+ int retval = 0;
+
+ if (!DeviceNodeIsOpened()) return false;
+
+ retval = ioctl(m_fd, IPA_IOC_COMMIT_RT, ip);
+ if (retval)
+ {
+ IPACMERR("Failed commiting routing rules.\n");
+ return false;
+ }
+
+ IPACMDBG_H("Commited routing rules to IPA HW.\n");
+ return true;
+}
+
+bool IPACM_Routing::Reset(enum ipa_ip_type ip)
+{
+ int retval = 0;
+
+ if (!DeviceNodeIsOpened()) return false;
+
+ retval = ioctl(m_fd, IPA_IOC_RESET_RT, ip);
+ retval |= ioctl(m_fd, IPA_IOC_COMMIT_RT, ip);
+ if (retval)
+ {
+ IPACMERR("Failed resetting routing block.\n");
+ return false;
+ }
+
+ IPACMDBG_H("Reset command issued to IPA routing block.\n");
+ return true;
+}
+
+bool IPACM_Routing::GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable)
+{
+ int retval = 0;
+
+ if (!DeviceNodeIsOpened()) return false;
+
+ retval = ioctl(m_fd, IPA_IOC_GET_RT_TBL, routingTable);
+ if (retval)
+ {
+ IPACMERR("IPA_IOCTL_GET_RT_TBL ioctl failed, routingTable =0x%p, retval=0x%x.\n", routingTable, retval);
+ return false;
+ }
+
+ IPACMDBG_H("IPA_IOCTL_GET_RT_TBL ioctl issued to IPA routing block.\n");
+ return true;
+}
+
+bool IPACM_Routing::PutRoutingTable(uint32_t routingTableHandle)
+{
+ int retval = 0;
+
+ if (!DeviceNodeIsOpened()) return false;
+
+ retval = ioctl(m_fd, IPA_IOC_PUT_RT_TBL, routingTableHandle);
+ if (retval)
+ {
+ IPACMERR("IPA_IOCTL_PUT_RT_TBL ioctl failed.\n");
+ return false;
+ }
+
+ IPACMDBG_H("IPA_IOCTL_PUT_RT_TBL ioctl issued to IPA routing block.\n");
+ return true;
+}
+
+bool IPACM_Routing::DeleteRoutingHdl(uint32_t rt_rule_hdl, ipa_ip_type ip)
+{
+ const uint8_t NUM_RULES = 1;
+ struct ipa_ioc_del_rt_rule *rt_rule;
+ struct ipa_rt_rule_del *rt_rule_entry;
+ bool res = true;
+ int len = 0;
+
+ if (rt_rule_hdl == 0)
+ {
+ IPACMERR(" No route handle passed. Ignoring it\n");
+ return res;
+ }
+
+ len = (sizeof(struct ipa_ioc_del_rt_rule)) + (NUM_RULES * sizeof(struct ipa_rt_rule_del));
+ rt_rule = (struct ipa_ioc_del_rt_rule *)malloc(len);
+ if (rt_rule == NULL)
+ {
+ IPACMERR("unable to allocate memory for del route rule\n");
+ return false;
+ }
+
+ memset(rt_rule, 0, len);
+ rt_rule->commit = 1;
+ rt_rule->num_hdls = NUM_RULES;
+ rt_rule->ip = ip;
+
+ rt_rule_entry = &rt_rule->hdl[0];
+ rt_rule_entry->status = -1;
+ rt_rule_entry->hdl = rt_rule_hdl;
+
+ IPACMDBG_H("Deleting Route hdl:(0x%x) with ip type: %d\n", rt_rule_entry->hdl, ip);
+ if ((false == DeleteRoutingRule(rt_rule)) ||
+ (rt_rule_entry->status))
+ {
+ PERROR("Routing rule deletion failed!\n");
+ goto fail;
+ res = false;
+ }
+
+fail:
+ free(rt_rule);
+
+ return res;
+}
+
+bool IPACM_Routing::ModifyRoutingRule(struct ipa_ioc_mdfy_rt_rule *mdfyRules)
+{
+ int retval = 0, cnt;
+
+ if (!DeviceNodeIsOpened())
+ {
+ IPACMERR("Device is not opened\n");
+ return false;
+ }
+
+ retval = ioctl(m_fd, IPA_IOC_MDFY_RT_RULE, mdfyRules);
+ if (retval)
+ {
+ IPACMERR("Failed modifying routing rules %p\n", mdfyRules);
+ return false;
+ }
+
+ for(cnt=0; cnt<mdfyRules->num_rules; cnt++)
+ {
+ if(mdfyRules->rules[cnt].status != 0)
+ {
+ IPACMERR("Unable to modify rule: %d\n", cnt);
+ }
+ }
+
+ IPACMDBG_H("Modified routing rules %p\n", mdfyRules);
+ return true;
+}