1 /*
2 Copyright (c) 2013 - 2017, 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
30 #include "ipa_nat_drv.h"
31 #include "ipa_nat_drvi.h"
32
33 /**
34 * ipa_nat_add_ipv4_tbl() - create ipv4 nat table
35 * @public_ip_addr: [in] public ipv4 address
36 * @number_of_entries: [in] number of nat entries
37 * @table_handle: [out] Handle of new ipv4 nat table
38 *
39 * To create new ipv4 nat table
40 *
41 * Returns: 0 On Success, negative on failure
42 */
ipa_nat_add_ipv4_tbl(uint32_t public_ip_addr,uint16_t number_of_entries,uint32_t * tbl_hdl)43 int ipa_nat_add_ipv4_tbl(uint32_t public_ip_addr,
44 uint16_t number_of_entries,
45 uint32_t *tbl_hdl)
46 {
47 int ret;
48
49 if (NULL == tbl_hdl || 0 == number_of_entries) {
50 IPAERR("Invalid parameters \n");
51 return -EINVAL;
52 }
53
54 ret = ipa_nati_add_ipv4_tbl(public_ip_addr,
55 number_of_entries,
56 tbl_hdl);
57 if (ret != 0) {
58 IPAERR("unable to add table \n");
59 return -EINVAL;
60 }
61 IPADBG("Returning table handle 0x%x\n", *tbl_hdl);
62
63 return ret;
64 } /* __ipa_nat_add_ipv4_tbl() */
65
66 /**
67 * ipa_nat_del_ipv4_tbl() - delete ipv4 table
68 * @table_handle: [in] Handle of ipv4 nat table
69 *
70 * To delete given ipv4 nat table
71 *
72 * Returns: 0 On Success, negative on failure
73 */
ipa_nat_del_ipv4_tbl(uint32_t tbl_hdl)74 int ipa_nat_del_ipv4_tbl(uint32_t tbl_hdl)
75 {
76 if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl ||
77 tbl_hdl > IPA_NAT_MAX_IP4_TBLS) {
78 IPAERR("invalid table handle passed \n");
79 return -EINVAL;
80 }
81 IPADBG("Passed Table Handle: 0x%x\n", tbl_hdl);
82
83 return ipa_nati_del_ipv4_table(tbl_hdl);
84 }
85
86 /**
87 * ipa_nat_add_ipv4_rule() - to insert new ipv4 rule
88 * @table_handle: [in] handle of ipv4 nat table
89 * @rule: [in] Pointer to new rule
90 * @rule_handle: [out] Return the handle to rule
91 *
92 * To insert new ipv4 nat rule into ipv4 nat table
93 *
94 * Returns: 0 On Success, negative on failure
95 */
ipa_nat_add_ipv4_rule(uint32_t tbl_hdl,const ipa_nat_ipv4_rule * clnt_rule,uint32_t * rule_hdl)96 int ipa_nat_add_ipv4_rule(uint32_t tbl_hdl,
97 const ipa_nat_ipv4_rule *clnt_rule,
98 uint32_t *rule_hdl)
99 {
100 int result = -EINVAL;
101
102 if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl ||
103 tbl_hdl > IPA_NAT_MAX_IP4_TBLS || NULL == rule_hdl ||
104 NULL == clnt_rule) {
105 IPAERR("invalide table handle passed \n");
106 return result;
107 }
108 IPADBG("Passed Table handle: 0x%x\n", tbl_hdl);
109
110 if (ipa_nati_add_ipv4_rule(tbl_hdl, clnt_rule, rule_hdl) != 0) {
111 return result;
112 }
113
114 IPADBG("returning rule handle 0x%x\n", *rule_hdl);
115 return 0;
116 }
117
118
119 /**
120 * ipa_nat_del_ipv4_rule() - to delete ipv4 nat rule
121 * @table_handle: [in] handle of ipv4 nat table
122 * @rule_handle: [in] ipv4 nat rule handle
123 *
124 * To insert new ipv4 nat rule into ipv4 nat table
125 *
126 * Returns: 0 On Success, negative on failure
127 */
ipa_nat_del_ipv4_rule(uint32_t tbl_hdl,uint32_t rule_hdl)128 int ipa_nat_del_ipv4_rule(uint32_t tbl_hdl,
129 uint32_t rule_hdl)
130 {
131 int result = -EINVAL;
132
133 if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl ||
134 IPA_NAT_INVALID_NAT_ENTRY == rule_hdl) {
135 IPAERR("invalide parameters\n");
136 return result;
137 }
138 IPADBG("Passed Table: 0x%x and rule handle 0x%x\n", tbl_hdl, rule_hdl);
139
140 result = ipa_nati_del_ipv4_rule(tbl_hdl, rule_hdl);
141 if (result) {
142 IPAERR("unable to delete rule from hw \n");
143 return result;
144 }
145
146 return 0;
147 }
148
149 /**
150 * ipa_nat_query_timestamp() - to query timestamp
151 * @table_handle: [in] handle of ipv4 nat table
152 * @rule_handle: [in] ipv4 nat rule handle
153 * @time_stamp: [out] time stamp of rule
154 *
155 * To retrieve the timestamp that lastly the
156 * nat rule was accessed
157 *
158 * Returns: 0 On Success, negative on failure
159 */
ipa_nat_query_timestamp(uint32_t tbl_hdl,uint32_t rule_hdl,uint32_t * time_stamp)160 int ipa_nat_query_timestamp(uint32_t tbl_hdl,
161 uint32_t rule_hdl,
162 uint32_t *time_stamp)
163 {
164
165 if (0 == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS ||
166 NULL == time_stamp) {
167 IPAERR("invalid parameters passed \n");
168 return -EINVAL;
169 }
170 IPADBG("Passed Table: 0x%x and rule handle 0x%x\n", tbl_hdl, rule_hdl);
171
172 return ipa_nati_query_timestamp(tbl_hdl, rule_hdl, time_stamp);
173 }
174
175
176 /**
177 * ipa_nat_modify_pdn() - modify single PDN entry in the PDN config table
178 * @table_handle: [in] handle of ipv4 nat table
179 * @pdn_index : [in] the index of the entry to be modified
180 * @pdn_info : [in] values for the PDN entry to be changed
181 *
182 * Modify a PDN entry
183 *
184 * Returns: 0 On Success, negative on failure
185 */
ipa_nat_modify_pdn(uint32_t tbl_hdl,uint8_t pdn_index,ipa_nat_pdn_entry * pdn_info)186 int ipa_nat_modify_pdn(uint32_t tbl_hdl,
187 uint8_t pdn_index,
188 ipa_nat_pdn_entry *pdn_info)
189 {
190 struct ipa_ioc_nat_pdn_entry pdn_data;
191
192 if (0 == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS) {
193 IPAERR("invalid parameters passed \n");
194 return -EINVAL;
195 }
196
197 if (!pdn_info) {
198 IPAERR("pdn_info is NULL \n");
199 return -EINVAL;
200 }
201
202 if (pdn_index > IPA_MAX_PDN_NUM) {
203 IPAERR("PDN index is out of range %d", pdn_index);
204 return -EINVAL;
205 }
206
207 pdn_data.pdn_index = pdn_index;
208 pdn_data.public_ip = pdn_info->public_ip;
209 pdn_data.src_metadata = pdn_info->src_metadata;
210 pdn_data.dst_metadata = pdn_info->dst_metadata;
211
212 return ipa_nati_modify_pdn(&pdn_data);
213 }
214
215
216