blob: 0b1400bda6cb1f5bb5c67d494ddace99a36510e5 [file] [log] [blame]
Sol Kavy879eb8b2014-04-07 19:11:31 -07001/*
2 **************************************************************************
3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
16
17/*
18 * nss_ipv6.c
19 * NSS IPv6 APIs
20 */
21#include <linux/ppp_channel.h>
22#include "nss_tx_rx_common.h"
Sol Kavy879eb8b2014-04-07 19:11:31 -070023
Vijay Dewangan4861f4e2014-10-14 16:56:35 -070024int nss_ipv6_conn_cfg __read_mostly = NSS_DEFAULT_NUM_CONN;
25static struct nss_conn_cfg_pvt i6cfgp;
Vijay Dewangan9db18752014-09-15 16:25:01 -070026
Sol Kavy879eb8b2014-04-07 19:11:31 -070027/*
28 * nss_ipv6_driver_conn_sync_update()
29 * Update driver specific information from the messsage.
30 */
31static void nss_ipv6_driver_conn_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics)
32{
33 struct nss_top_instance *nss_top = nss_ctx->nss_top;
34 struct net_device *pppoe_dev = NULL;
35
36 /*
37 * Update statistics maintained by NSS driver
38 */
39 spin_lock_bh(&nss_top->stats_lock);
40 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_PKTS] += nics->flow_rx_packet_count + nics->return_rx_packet_count;
41 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_BYTES] += nics->flow_rx_byte_count + nics->return_rx_byte_count;
42 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_PKTS] += nics->flow_tx_packet_count + nics->return_tx_packet_count;
43 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_BYTES] += nics->flow_tx_byte_count + nics->return_tx_byte_count;
Abhishek Rastogi55f39452014-05-08 19:23:29 +053044 spin_unlock_bh(&nss_top->stats_lock);
Sol Kavy879eb8b2014-04-07 19:11:31 -070045
46 /*
47 * Update the PPPoE interface stats, if there is any PPPoE session on the interfaces.
48 */
49 if (nics->flow_pppoe_session_id) {
50 pppoe_dev = ppp_session_to_netdev(nics->flow_pppoe_session_id, (uint8_t *)nics->flow_pppoe_remote_mac);
51 if (pppoe_dev) {
52 ppp_update_stats(pppoe_dev, nics->flow_rx_packet_count, nics->flow_rx_byte_count,
53 nics->flow_tx_packet_count, nics->flow_tx_byte_count);
54 dev_put(pppoe_dev);
55 }
56 }
57
58 if (nics->return_pppoe_session_id) {
59 pppoe_dev = ppp_session_to_netdev(nics->return_pppoe_session_id, (uint8_t *)nics->return_pppoe_remote_mac);
60 if (pppoe_dev) {
61 ppp_update_stats(pppoe_dev, nics->return_rx_packet_count, nics->return_rx_byte_count,
62 nics->return_tx_packet_count, nics->return_tx_byte_count);
63 dev_put(pppoe_dev);
64 }
65 }
Sol Kavy879eb8b2014-04-07 19:11:31 -070066}
67
68/*
Murat Sezgin0c0561d2014-04-09 18:55:58 -070069 * nss_ipv6_driver_node_sync_update)
70 * Update driver specific information from the messsage.
71 */
72static void nss_ipv6_driver_node_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins)
73{
74 struct nss_top_instance *nss_top = nss_ctx->nss_top;
75 uint32_t i;
76
77 /*
78 * Update statistics maintained by NSS driver
79 */
80 spin_lock_bh(&nss_top->stats_lock);
81 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
82 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
83 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_DROPPED] += nins->node_stats.rx_dropped;
84 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
85 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
86
Murat Sezgin0c0561d2014-04-09 18:55:58 -070087 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_REQUESTS] += nins->ipv6_connection_create_requests;
88 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_COLLISIONS] += nins->ipv6_connection_create_collisions;
89 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_connection_create_invalid_interface;
90 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_connection_destroy_requests;
91 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_MISSES] += nins->ipv6_connection_destroy_misses;
92 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_HITS] += nins->ipv6_connection_hash_hits;
93 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_REORDERS] += nins->ipv6_connection_hash_reorders;
94 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_FLUSHES] += nins->ipv6_connection_flushes;
95 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_EVICTIONS] += nins->ipv6_connection_evictions;
96
97 for (i = 0; i < NSS_EXCEPTION_EVENT_IPV6_MAX; i++) {
98 nss_top->stats_if_exception_ipv6[i] += nins->exception_events[i];
99 }
100 spin_unlock_bh(&nss_top->stats_lock);
101}
102
103/*
Sol Kavy879eb8b2014-04-07 19:11:31 -0700104 * nss_ipv6_rx_msg_handler()
105 * Handle NSS -> HLOS messages for IPv6 bridge/route
106 */
107static void nss_ipv6_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
108{
109 struct nss_ipv6_msg *nim = (struct nss_ipv6_msg *)ncm;
110 nss_ipv6_msg_callback_t cb;
111
112 BUG_ON(ncm->interface != NSS_IPV6_RX_INTERFACE);
113
114 /*
115 * Is this a valid request/response packet?
116 */
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700117 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700118 nss_warning("%p: received invalid message %d for IPv6 interface", nss_ctx, nim->cm.type);
119 return;
120 }
121
122 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
123 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
124 return;
125 }
126
127 /*
128 * Log failures
129 */
130 nss_core_log_msg_failures(nss_ctx, ncm);
131
132 /*
133 * Handle deprecated messages. Eventually these messages should be removed.
134 */
135 switch (nim->cm.type) {
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700136 case NSS_IPV6_RX_NODE_STATS_SYNC_MSG:
137 /*
138 * Update driver statistics on node sync.
139 */
140 nss_ipv6_driver_node_sync_update(nss_ctx, &nim->msg.node_stats);
141 break;
142
Sol Kavy879eb8b2014-04-07 19:11:31 -0700143 case NSS_IPV6_RX_CONN_STATS_SYNC_MSG:
144 /*
145 * Update driver statistics on connection sync.
146 */
147 nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
Sakthi Vignesh Radhakrishnan515f8c22014-06-21 15:04:19 -0700148 break;
Sol Kavy879eb8b2014-04-07 19:11:31 -0700149 }
Abhishek Rastogi55f39452014-05-08 19:23:29 +0530150
Sol Kavy879eb8b2014-04-07 19:11:31 -0700151 /*
152 * Update the callback and app_data for NOTIFY messages, IPv6 sends all notify messages
153 * to the same callback/app_data.
154 */
155 if (nim->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
156 ncm->cb = (uint32_t)nss_ctx->nss_top->ipv6_callback;
157 ncm->app_data = (uint32_t)nss_ctx->nss_top->ipv6_ctx;
158 }
159
160 /*
161 * Do we have a callback?
162 */
163 if (!ncm->cb) {
164 return;
165 }
166
167 /*
168 * Callback
169 */
170 cb = (nss_ipv6_msg_callback_t)ncm->cb;
171 cb((void *)ncm->app_data, nim);
172}
173
174/*
175 * nss_ipv6_tx()
176 * Transmit an ipv6 message to the FW.
177 */
178nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
179{
180 struct nss_ipv6_msg *nim2;
181 struct nss_cmn_msg *ncm = &nim->cm;
182 struct sk_buff *nbuf;
183 int32_t status;
184
185 NSS_VERIFY_CTX_MAGIC(nss_ctx);
186 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
187 nss_warning("%p: ipv6 msg dropped as core not ready", nss_ctx);
188 return NSS_TX_FAILURE_NOT_READY;
189 }
190
191 /*
192 * Sanity check the message
193 */
194 if (ncm->interface != NSS_IPV6_RX_INTERFACE) {
195 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
196 return NSS_TX_FAILURE;
197 }
198
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700199 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700200 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
201 return NSS_TX_FAILURE;
202 }
203
204 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
205 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
206 return NSS_TX_FAILURE;
207 }
208
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530209 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700210 if (unlikely(!nbuf)) {
211 spin_lock_bh(&nss_ctx->nss_top->stats_lock);
212 nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]++;
213 spin_unlock_bh(&nss_ctx->nss_top->stats_lock);
214 nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
215 return NSS_TX_FAILURE;
216 }
217
218 /*
219 * Copy the message to our skb.
220 */
221 nim2 = (struct nss_ipv6_msg *)skb_put(nbuf, sizeof(struct nss_ipv6_msg));
222 memcpy(nim2, nim, sizeof(struct nss_ipv6_msg));
223
224 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
225 if (status != NSS_CORE_STATUS_SUCCESS) {
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530226 dev_kfree_skb_any(nbuf);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700227 nss_warning("%p: Unable to enqueue 'Destroy IPv6' rule\n", nss_ctx);
228 return NSS_TX_FAILURE;
229 }
230
231 nss_hal_send_interrupt(nss_ctx->nmap, nss_ctx->h2n_desc_rings[NSS_IF_CMD_QUEUE].desc_ring.int_bit,
232 NSS_REGS_H2N_INTR_STATUS_DATA_COMMAND_QUEUE);
233
234 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
235 return NSS_TX_SUCCESS;
236}
237
238/*
239 **********************************
240 Register/Unregister/Miscellaneous APIs
241 **********************************
242 */
243
244/*
245 * nss_ipv6_notify_register()
246 * Register to received IPv6 events.
247 *
248 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
249 */
250struct nss_ctx_instance *nss_ipv6_notify_register(nss_ipv6_msg_callback_t cb, void *app_data)
251{
252 /*
253 * TODO: We need to have a new array in support of the new API
254 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
255 */
256 nss_top_main.ipv6_callback = cb;
257 nss_top_main.ipv6_ctx = app_data;
258 return &nss_top_main.nss[nss_top_main.ipv6_handler_id];
259}
260
261/*
262 * nss_ipv6_notify_unregister()
263 * Unregister to received IPv6 events.
264 *
265 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
266 */
267void nss_ipv6_notify_unregister(void)
268{
269 nss_top_main.ipv6_callback = NULL;
270}
271
272/*
273 * nss_ipv6_get_mgr()
274 *
275 * TODO: This only suppports a single ipv6, do we ever want to support more?
276 */
277struct nss_ctx_instance *nss_ipv6_get_mgr(void)
278{
279 return (void *)&nss_top_main.nss[nss_top_main.ipv6_handler_id];
280}
281
282/*
283 * nss_ipv6_register_handler()
284 * Register our handler to receive messages for this interface
285 */
286void nss_ipv6_register_handler()
287{
288 if (nss_core_register_handler(NSS_IPV6_RX_INTERFACE, nss_ipv6_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
289 nss_warning("IPv6 handler failed to register");
290 }
291}
292
Vijay Dewangan9db18752014-09-15 16:25:01 -0700293/*
294 * nss_ipv6_conn_cfg_callback()
295 * call back function for the ipv6 connection configuration handler
296 */
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700297static void nss_ipv6_conn_cfg_callback(void *app_data, struct nss_ipv6_msg *nim)
Vijay Dewangan9db18752014-09-15 16:25:01 -0700298{
299 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700300 /*
301 * Error, hence we are not updating the nss_ipv4_conn_cfg
302 * Restore the current_value to its previous state
303 */
304 i6cfgp.response = FAILURE;
305 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700306 return;
307 }
308
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700309 /*
310 * Sucess at NSS FW, hence updating nss_ipv4_conn_cfg, with the valid value
311 * saved at the sysctl handler.
312 */
Vijay Dewangan9db18752014-09-15 16:25:01 -0700313 nss_info("IPv6 connection configuration success: %d\n", nim->cm.error);
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700314 i6cfgp.response = SUCCESS;
315 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700316}
317
318
319/*
320 * nss_ipv6_conn_cfg_handler()
321 * Sets the number of connections for IPv6
322 */
323static int nss_ipv6_conn_cfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
324{
325 struct nss_top_instance *nss_top = &nss_top_main;
326 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
327 struct nss_ipv6_msg nim;
328 struct nss_ipv6_rule_conn_cfg_msg *nirccm;
329 nss_tx_status_t nss_tx_status;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700330 int ret = FAILURE;
331 uint32_t sum_of_conn;
332
333 /*
334 * Acquiring semaphore
335 */
336 down(&i6cfgp.sem);
337
338 /*
339 * Take a snapshot of the current value
340 */
341 i6cfgp.current_value = nss_ipv6_conn_cfg;
342
343 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
344 if (ret || (!write)) {
345 up(&i6cfgp.sem);
346 return ret;
347 }
Vijay Dewangan9db18752014-09-15 16:25:01 -0700348
349 /*
350 * Specifications for input
351 * 1) The input should be power of 2.
352 * 2) Input for ipv4 and ipv6 sum togther should not exceed 8k
353 * 3) Min. value should be at leat 256 connections. This is the
354 * minimum connections we will support for each of them.
355 */
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700356 sum_of_conn = nss_ipv4_conn_cfg + nss_ipv6_conn_cfg;
357 if ((nss_ipv6_conn_cfg & NSS_NUM_CONN_QUANTA_MASK) ||
358 (sum_of_conn > NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6) ||
359 (nss_ipv6_conn_cfg < NSS_MIN_NUM_CONN)) {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700360 nss_warning("%p: input supported connections (%d) does not adhere\
361 specifications\n1) not power of 2,\n2) is less than \
362 min val: %d, OR\n IPv4/6 total exceeds %d\n",
363 nss_ctx,
364 nss_ipv6_conn_cfg,
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700365 NSS_MIN_NUM_CONN,
366 NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6);
367
368 /*
369 * Restore the current_value to its previous state
370 */
371 nss_ipv6_conn_cfg = i6cfgp.current_value;
372 up(&i6cfgp.sem);
373 return FAILURE;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700374 }
375
Vijay Dewangan9db18752014-09-15 16:25:01 -0700376
377 nss_info("%p: IPv6 supported connections: %d\n", nss_ctx, nss_ipv6_conn_cfg);
378
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700379 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_CFG_RULE_MSG,
380 sizeof(struct nss_ipv6_rule_conn_cfg_msg), (nss_ipv6_msg_callback_t *)nss_ipv6_conn_cfg_callback, NULL);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700381
382 nirccm = &nim.msg.rule_conn_cfg;
383 nirccm->num_conn = htonl(nss_ipv6_conn_cfg);
384 nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
385
386 if (nss_tx_status != NSS_TX_SUCCESS) {
387 nss_warning("%p: nss_tx error setting IPv6 Connections: %d\n",
388 nss_ctx,
389 nss_ipv6_conn_cfg);
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700390
391 /*
392 * Restore the current_value to its previous state
393 */
394 nss_ipv6_conn_cfg = i6cfgp.current_value;
395 up(&i6cfgp.sem);
396 return FAILURE;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700397 }
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700398
399 /*
400 * Blocking call, wait till we get ACK for this msg.
401 */
402 ret = wait_for_completion_timeout(&i6cfgp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
403 if (ret == 0) {
404 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
405
406 /*
407 * Restore the current_value to its previous state
408 */
409 nss_ipv6_conn_cfg = i6cfgp.current_value;
410 up(&i6cfgp.sem);
411 return FAILURE;
412 }
413
414 /*
415 * ACK/NACK received from NSS FW
416 * If ACK: Callback function will update nss_ipv4_conn_cfg with
417 * i6cfgp.num_conn_valid, which holds the user input
418 */
419 if (FAILURE == i6cfgp.response) {
420 /*
421 * Restore the current_value to its previous state
422 */
423 nss_ipv6_conn_cfg = i6cfgp.current_value;
424 up(&i6cfgp.sem);
425 return FAILURE;
426 }
427
428 up(&i6cfgp.sem);
429 return SUCCESS;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700430}
431
432static ctl_table nss_ipv6_table[] = {
433 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700434 .procname = "ipv6_conn",
435 .data = &nss_ipv6_conn_cfg,
436 .maxlen = sizeof(int),
437 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700438 .proc_handler = &nss_ipv6_conn_cfg_handler,
439 },
440 { }
441};
442
443static ctl_table nss_ipv6_dir[] = {
444 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700445 .procname = "ipv6cfg",
446 .mode = 0555,
447 .child = nss_ipv6_table,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700448 },
449 { }
450};
451
452static ctl_table nss_ipv6_root_dir[] = {
453 {
454 .procname = "nss",
455 .mode = 0555,
456 .child = nss_ipv6_dir,
457 },
458 { }
459};
460
461static ctl_table nss_ipv6_root[] = {
462 {
463 .procname = "dev",
464 .mode = 0555,
465 .child = nss_ipv6_root_dir,
466 },
467 { }
468};
469
470static struct ctl_table_header *nss_ipv6_header;
471
472/*
473 * nss_ipv6_register_sysctl()
474 * Register sysctl specific to ipv4
475 */
476void nss_ipv6_register_sysctl(void)
477{
478 /*
479 * Register sysctl table.
480 */
481 nss_ipv6_header = register_sysctl_table(nss_ipv6_root);
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700482 sema_init(&i6cfgp.sem, 1);
483 init_completion(&i6cfgp.complete);
484 i6cfgp.current_value = nss_ipv6_conn_cfg;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700485}
486
487/*
488 * nss_ipv6_unregister_sysctl()
489 * Unregister sysctl specific to ipv4
490 */
491void nss_ipv6_unregister_sysctl(void)
492{
493 /*
494 * Unregister sysctl table.
495 */
496 if (nss_ipv6_header) {
497 unregister_sysctl_table(nss_ipv6_header);
498 }
499}
500
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700501/*
502 * nss_ipv6_msg_init()
503 * Initialize IPv6 message.
504 */
505void nss_ipv6_msg_init(struct nss_ipv6_msg *nim, uint16_t if_num, uint32_t type, uint32_t len,
506 nss_ipv6_msg_callback_t *cb, void *app_data)
507{
508 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
509}
510
Sol Kavy879eb8b2014-04-07 19:11:31 -0700511EXPORT_SYMBOL(nss_ipv6_tx);
512EXPORT_SYMBOL(nss_ipv6_notify_register);
513EXPORT_SYMBOL(nss_ipv6_notify_unregister);
514EXPORT_SYMBOL(nss_ipv6_get_mgr);
515EXPORT_SYMBOL(nss_ipv6_register_handler);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700516EXPORT_SYMBOL(nss_ipv6_register_sysctl);
517EXPORT_SYMBOL(nss_ipv6_unregister_sysctl);
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700518EXPORT_SYMBOL(nss_ipv6_msg_init);