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 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 56 IPACM_Header::~IPACM_Header() 57 { 58 if (-1 != m_fd) 59 { 60 close(m_fd); 61 } 62 } 63 64 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 65 66 bool IPACM_Header::DeviceNodeIsOpened() 67 { 68 return (-1 != m_fd); 69 } 70 71 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 72 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 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 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 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 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 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 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 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 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