1 /*
2 Copyright (c) 2013, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #include <unistd.h>
30 #include <sys/ioctl.h>
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 #include "IPACM_Header.h"
36 #include "IPACM_Log.h"
37
38 /////////////////////////////////////////////////////////////////////////////////////////////////////////
39
40 //All interaction through the driver are made through this inode.
41 static const char *DEVICE_NAME = "/dev/ipa";
42
43 /////////////////////////////////////////////////////////////////////////////////////////////////////////
44
IPACM_Header()45 IPACM_Header::IPACM_Header()
46 {
47 m_fd = open(DEVICE_NAME, O_RDWR);
48 if (-1 == m_fd)
49 {
50 IPACMERR("Failed to open %s in IPACM_Header test application constructor.\n", DEVICE_NAME);
51 }
52 }
53
54 /////////////////////////////////////////////////////////////////////////////////////////////////////////
55
~IPACM_Header()56 IPACM_Header::~IPACM_Header()
57 {
58 if (-1 != m_fd)
59 {
60 close(m_fd);
61 }
62 }
63
64 /////////////////////////////////////////////////////////////////////////////////////////////////////////
65
DeviceNodeIsOpened()66 bool IPACM_Header::DeviceNodeIsOpened()
67 {
68 return (-1 != m_fd);
69 }
70
71 /////////////////////////////////////////////////////////////////////////////////////////////////////////
72
AddHeader(struct ipa_ioc_add_hdr * pHeaderTableToAdd)73 bool IPACM_Header::AddHeader(struct ipa_ioc_add_hdr *pHeaderTableToAdd)
74 {
75 int nRetVal = 0;
76 //call the Driver ioctl in order to add header
77 nRetVal = ioctl(m_fd, IPA_IOC_ADD_HDR, pHeaderTableToAdd);
78 IPACMDBG("return value: %d\n", nRetVal);
79 return (-1 != nRetVal);
80 }
81
82 /////////////////////////////////////////////////////////////////////////////////////////////////////////
83
DeleteHeader(struct ipa_ioc_del_hdr * pHeaderTableToDelete)84 bool IPACM_Header::DeleteHeader(struct ipa_ioc_del_hdr *pHeaderTableToDelete)
85 {
86 int nRetVal = 0;
87 //call the Driver ioctl in order to remove header
88 nRetVal = ioctl(m_fd, IPA_IOC_DEL_HDR, pHeaderTableToDelete);
89 IPACMDBG("return value: %d\n", nRetVal);
90 return (-1 != nRetVal);
91 }
92
93 /////////////////////////////////////////////////////////////////////////////////////////////////////////
94
Commit()95 bool IPACM_Header::Commit()
96 {
97 int nRetVal = 0;
98 nRetVal = ioctl(m_fd, IPA_IOC_COMMIT_HDR);
99 IPACMDBG("return value: %d\n", nRetVal);
100 return true;
101 }
102
103 /////////////////////////////////////////////////////////////////////////////////////////////////////////
104
Reset()105 bool IPACM_Header::Reset()
106 {
107 int nRetVal = 0;
108
109 nRetVal = ioctl(m_fd, IPA_IOC_RESET_HDR);
110 nRetVal |= ioctl(m_fd, IPA_IOC_COMMIT_HDR);
111 IPACMDBG("return value: %d\n", nRetVal);
112 return true;
113 }
114
115 /////////////////////////////////////////////////////////////////////////////////////////////////////////
116
GetHeaderHandle(struct ipa_ioc_get_hdr * pHeaderStruct)117 bool IPACM_Header::GetHeaderHandle(struct ipa_ioc_get_hdr *pHeaderStruct)
118 {
119 int retval = 0;
120
121 if (!DeviceNodeIsOpened()) return false;
122
123 retval = ioctl(m_fd, IPA_IOC_GET_HDR, pHeaderStruct);
124 if (retval)
125 {
126 IPACMERR("IPA_IOC_GET_HDR ioctl failed, routingTable =0x%p, retval=0x%x.\n", pHeaderStruct, retval);
127 return false;
128 }
129
130 IPACMDBG("IPA_IOC_GET_HDR ioctl issued to IPA header insertion block.\n");
131 return true;
132 }
133
134 /////////////////////////////////////////////////////////////////////////////////////////////////////////
135
CopyHeader(struct ipa_ioc_copy_hdr * pCopyHeaderStruct)136 bool IPACM_Header::CopyHeader(struct ipa_ioc_copy_hdr *pCopyHeaderStruct)
137 {
138 int retval = 0;
139
140 if (!DeviceNodeIsOpened()) return false;
141
142 retval = ioctl(m_fd, IPA_IOC_COPY_HDR, pCopyHeaderStruct);
143 if (retval)
144 {
145 IPACMERR("IPA_IOC_COPY_HDR ioctl failed, retval=0x%x.\n", retval);
146 return false;
147 }
148
149 IPACMDBG("IPA_IOC_COPY_HDR ioctl issued to IPA header insertion block.\n");
150 return true;
151 }
152
DeleteHeaderHdl(uint32_t hdr_hdl)153 bool IPACM_Header::DeleteHeaderHdl(uint32_t hdr_hdl)
154 {
155 const uint8_t NUM_HDLS = 1;
156 struct ipa_ioc_del_hdr *pHeaderDescriptor = NULL;
157 struct ipa_hdr_del *hd_rule_entry;
158 int len = 0;
159 bool res = true;
160
161 if (hdr_hdl == 0)
162 {
163 IPACMERR("Invalid header handle passed. Ignoring it\n");
164 return false;
165 }
166
167 len = (sizeof(struct ipa_ioc_del_hdr)) + (NUM_HDLS * sizeof(struct ipa_hdr_del));
168 pHeaderDescriptor = (struct ipa_ioc_del_hdr *)malloc(len);
169 if (pHeaderDescriptor == NULL)
170 {
171 IPACMERR("Unable to allocate memory for del header\n");
172 return false;
173 }
174
175 memset(pHeaderDescriptor, 0, len);
176 pHeaderDescriptor->commit = true;
177 pHeaderDescriptor->num_hdls = NUM_HDLS;
178 hd_rule_entry = &pHeaderDescriptor->hdl[0];
179
180 hd_rule_entry->hdl = hdr_hdl;
181 hd_rule_entry->status = -1;
182
183 IPACMDBG("Deleting Header hdl:(%x)\n", hd_rule_entry->hdl);
184 if ((false == DeleteHeader(pHeaderDescriptor)) ||
185 (hd_rule_entry->status))
186 {
187 IPACMERR("Header hdl:(%x) deletion failed! status: %d\n", hd_rule_entry->hdl,hd_rule_entry->status);
188 res = false;
189 goto fail;
190 }
191
192 IPACMDBG_H("Deleted Header hdl:(%x) successfully\n", hd_rule_entry->hdl);
193
194 fail:
195 free(pHeaderDescriptor);
196
197 return res;
198
199 }
200
AddHeaderProcCtx(struct ipa_ioc_add_hdr_proc_ctx * pHeader)201 bool IPACM_Header::AddHeaderProcCtx(struct ipa_ioc_add_hdr_proc_ctx* pHeader)
202 {
203 int ret = 0;
204 //call the Driver ioctl to add header processing context
205 ret = ioctl(m_fd, IPA_IOC_ADD_HDR_PROC_CTX, pHeader);
206 return (ret == 0);
207 }
208
DeleteHeaderProcCtx(uint32_t hdl)209 bool IPACM_Header::DeleteHeaderProcCtx(uint32_t hdl)
210 {
211 int len, ret;
212 struct ipa_ioc_del_hdr_proc_ctx* pHeaderTable = NULL;
213
214 len = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_del);
215 pHeaderTable = (struct ipa_ioc_del_hdr_proc_ctx*)malloc(len);
216 if(pHeaderTable == NULL)
217 {
218 IPACMERR("Failed to allocate buffer.\n");
219 return false;
220 }
221 memset(pHeaderTable, 0, len);
222
223 pHeaderTable->commit = 1;
224 pHeaderTable->num_hdls = 1;
225 pHeaderTable->hdl[0].hdl = hdl;
226
227 ret = ioctl(m_fd, IPA_IOC_DEL_HDR_PROC_CTX, pHeaderTable);
228 if(ret != 0)
229 {
230 IPACMERR("Failed to delete hdr proc ctx: return value %d, status %d\n",
231 ret, pHeaderTable->hdl[0].status);
232 }
233 free(pHeaderTable);
234 return (ret == 0);
235 }
236
237