blob: 625641521684944b615f4c150f8422b1194a69c5 [file] [log] [blame]
Sol Kavy879eb8b2014-04-07 19:11:31 -07001/*
2 **************************************************************************
Vijay Dewangan488e5372014-12-29 21:40:11 -08003 * Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
Sol Kavy879eb8b2014-04-07 19:11:31 -07004 * 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 */
Sol Kavy879eb8b2014-04-07 19:11:31 -070021#include "nss_tx_rx_common.h"
Sol Kavy879eb8b2014-04-07 19:11:31 -070022
Vijay Dewangan4861f4e2014-10-14 16:56:35 -070023int nss_ipv6_conn_cfg __read_mostly = NSS_DEFAULT_NUM_CONN;
24static struct nss_conn_cfg_pvt i6cfgp;
Vijay Dewangan9db18752014-09-15 16:25:01 -070025
Sol Kavy879eb8b2014-04-07 19:11:31 -070026/*
27 * nss_ipv6_driver_conn_sync_update()
28 * Update driver specific information from the messsage.
29 */
30static void nss_ipv6_driver_conn_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics)
31{
32 struct nss_top_instance *nss_top = nss_ctx->nss_top;
Sol Kavy879eb8b2014-04-07 19:11:31 -070033
34 /*
35 * Update statistics maintained by NSS driver
36 */
37 spin_lock_bh(&nss_top->stats_lock);
38 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_PKTS] += nics->flow_rx_packet_count + nics->return_rx_packet_count;
39 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_BYTES] += nics->flow_rx_byte_count + nics->return_rx_byte_count;
40 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_PKTS] += nics->flow_tx_packet_count + nics->return_tx_packet_count;
41 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 +053042 spin_unlock_bh(&nss_top->stats_lock);
Sol Kavy879eb8b2014-04-07 19:11:31 -070043}
44
45/*
Murat Sezgin0c0561d2014-04-09 18:55:58 -070046 * nss_ipv6_driver_node_sync_update)
47 * Update driver specific information from the messsage.
48 */
49static void nss_ipv6_driver_node_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins)
50{
51 struct nss_top_instance *nss_top = nss_ctx->nss_top;
52 uint32_t i;
53
54 /*
55 * Update statistics maintained by NSS driver
56 */
57 spin_lock_bh(&nss_top->stats_lock);
58 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
59 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
60 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_DROPPED] += nins->node_stats.rx_dropped;
61 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
62 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
63
Murat Sezgin0c0561d2014-04-09 18:55:58 -070064 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_REQUESTS] += nins->ipv6_connection_create_requests;
65 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_COLLISIONS] += nins->ipv6_connection_create_collisions;
66 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_connection_create_invalid_interface;
67 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_connection_destroy_requests;
68 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_MISSES] += nins->ipv6_connection_destroy_misses;
69 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_HITS] += nins->ipv6_connection_hash_hits;
70 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_REORDERS] += nins->ipv6_connection_hash_reorders;
71 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_FLUSHES] += nins->ipv6_connection_flushes;
72 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_EVICTIONS] += nins->ipv6_connection_evictions;
73
74 for (i = 0; i < NSS_EXCEPTION_EVENT_IPV6_MAX; i++) {
75 nss_top->stats_if_exception_ipv6[i] += nins->exception_events[i];
76 }
77 spin_unlock_bh(&nss_top->stats_lock);
78}
79
80/*
Sol Kavy879eb8b2014-04-07 19:11:31 -070081 * nss_ipv6_rx_msg_handler()
82 * Handle NSS -> HLOS messages for IPv6 bridge/route
83 */
84static void nss_ipv6_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
85{
86 struct nss_ipv6_msg *nim = (struct nss_ipv6_msg *)ncm;
87 nss_ipv6_msg_callback_t cb;
88
89 BUG_ON(ncm->interface != NSS_IPV6_RX_INTERFACE);
90
91 /*
92 * Is this a valid request/response packet?
93 */
Murat Sezgin5c8c7362014-09-02 17:58:21 -070094 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -070095 nss_warning("%p: received invalid message %d for IPv6 interface", nss_ctx, nim->cm.type);
96 return;
97 }
98
99 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
100 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
101 return;
102 }
103
104 /*
105 * Log failures
106 */
107 nss_core_log_msg_failures(nss_ctx, ncm);
108
109 /*
110 * Handle deprecated messages. Eventually these messages should be removed.
111 */
112 switch (nim->cm.type) {
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700113 case NSS_IPV6_RX_NODE_STATS_SYNC_MSG:
114 /*
115 * Update driver statistics on node sync.
116 */
117 nss_ipv6_driver_node_sync_update(nss_ctx, &nim->msg.node_stats);
118 break;
119
Sol Kavy879eb8b2014-04-07 19:11:31 -0700120 case NSS_IPV6_RX_CONN_STATS_SYNC_MSG:
121 /*
122 * Update driver statistics on connection sync.
123 */
124 nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
Sakthi Vignesh Radhakrishnan515f8c22014-06-21 15:04:19 -0700125 break;
Sol Kavy879eb8b2014-04-07 19:11:31 -0700126 }
Abhishek Rastogi55f39452014-05-08 19:23:29 +0530127
Sol Kavy879eb8b2014-04-07 19:11:31 -0700128 /*
129 * Update the callback and app_data for NOTIFY messages, IPv6 sends all notify messages
130 * to the same callback/app_data.
131 */
132 if (nim->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
133 ncm->cb = (uint32_t)nss_ctx->nss_top->ipv6_callback;
134 ncm->app_data = (uint32_t)nss_ctx->nss_top->ipv6_ctx;
135 }
136
137 /*
138 * Do we have a callback?
139 */
140 if (!ncm->cb) {
141 return;
142 }
143
144 /*
145 * Callback
146 */
147 cb = (nss_ipv6_msg_callback_t)ncm->cb;
148 cb((void *)ncm->app_data, nim);
149}
150
151/*
152 * nss_ipv6_tx()
153 * Transmit an ipv6 message to the FW.
154 */
155nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
156{
157 struct nss_ipv6_msg *nim2;
158 struct nss_cmn_msg *ncm = &nim->cm;
159 struct sk_buff *nbuf;
160 int32_t status;
161
162 NSS_VERIFY_CTX_MAGIC(nss_ctx);
163 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
164 nss_warning("%p: ipv6 msg dropped as core not ready", nss_ctx);
165 return NSS_TX_FAILURE_NOT_READY;
166 }
167
168 /*
169 * Sanity check the message
170 */
171 if (ncm->interface != NSS_IPV6_RX_INTERFACE) {
172 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
173 return NSS_TX_FAILURE;
174 }
175
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700176 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700177 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
178 return NSS_TX_FAILURE;
179 }
180
181 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
182 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
183 return NSS_TX_FAILURE;
184 }
185
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530186 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700187 if (unlikely(!nbuf)) {
188 spin_lock_bh(&nss_ctx->nss_top->stats_lock);
189 nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]++;
190 spin_unlock_bh(&nss_ctx->nss_top->stats_lock);
191 nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
192 return NSS_TX_FAILURE;
193 }
194
195 /*
196 * Copy the message to our skb.
197 */
198 nim2 = (struct nss_ipv6_msg *)skb_put(nbuf, sizeof(struct nss_ipv6_msg));
199 memcpy(nim2, nim, sizeof(struct nss_ipv6_msg));
200
201 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
202 if (status != NSS_CORE_STATUS_SUCCESS) {
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530203 dev_kfree_skb_any(nbuf);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700204 nss_warning("%p: Unable to enqueue 'Destroy IPv6' rule\n", nss_ctx);
205 return NSS_TX_FAILURE;
206 }
207
208 nss_hal_send_interrupt(nss_ctx->nmap, nss_ctx->h2n_desc_rings[NSS_IF_CMD_QUEUE].desc_ring.int_bit,
209 NSS_REGS_H2N_INTR_STATUS_DATA_COMMAND_QUEUE);
210
211 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
212 return NSS_TX_SUCCESS;
213}
214
215/*
216 **********************************
217 Register/Unregister/Miscellaneous APIs
218 **********************************
219 */
220
221/*
222 * nss_ipv6_notify_register()
223 * Register to received IPv6 events.
224 *
225 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
226 */
227struct nss_ctx_instance *nss_ipv6_notify_register(nss_ipv6_msg_callback_t cb, void *app_data)
228{
229 /*
230 * TODO: We need to have a new array in support of the new API
231 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
232 */
233 nss_top_main.ipv6_callback = cb;
234 nss_top_main.ipv6_ctx = app_data;
235 return &nss_top_main.nss[nss_top_main.ipv6_handler_id];
236}
237
238/*
239 * nss_ipv6_notify_unregister()
240 * Unregister to received IPv6 events.
241 *
242 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
243 */
244void nss_ipv6_notify_unregister(void)
245{
246 nss_top_main.ipv6_callback = NULL;
247}
248
249/*
250 * nss_ipv6_get_mgr()
251 *
252 * TODO: This only suppports a single ipv6, do we ever want to support more?
253 */
254struct nss_ctx_instance *nss_ipv6_get_mgr(void)
255{
256 return (void *)&nss_top_main.nss[nss_top_main.ipv6_handler_id];
257}
258
259/*
260 * nss_ipv6_register_handler()
261 * Register our handler to receive messages for this interface
262 */
263void nss_ipv6_register_handler()
264{
265 if (nss_core_register_handler(NSS_IPV6_RX_INTERFACE, nss_ipv6_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
266 nss_warning("IPv6 handler failed to register");
267 }
268}
269
Vijay Dewangan9db18752014-09-15 16:25:01 -0700270/*
271 * nss_ipv6_conn_cfg_callback()
272 * call back function for the ipv6 connection configuration handler
273 */
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700274static void nss_ipv6_conn_cfg_callback(void *app_data, struct nss_ipv6_msg *nim)
Vijay Dewangan9db18752014-09-15 16:25:01 -0700275{
276 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700277 /*
278 * Error, hence we are not updating the nss_ipv4_conn_cfg
279 * Restore the current_value to its previous state
280 */
Vijay Dewangan488e5372014-12-29 21:40:11 -0800281 i6cfgp.response = NSS_FAILURE;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700282 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700283 return;
284 }
285
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700286 /*
287 * Sucess at NSS FW, hence updating nss_ipv4_conn_cfg, with the valid value
288 * saved at the sysctl handler.
289 */
Vijay Dewangan9db18752014-09-15 16:25:01 -0700290 nss_info("IPv6 connection configuration success: %d\n", nim->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800291 i6cfgp.response = NSS_SUCCESS;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700292 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700293}
294
295
296/*
297 * nss_ipv6_conn_cfg_handler()
298 * Sets the number of connections for IPv6
299 */
300static int nss_ipv6_conn_cfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
301{
302 struct nss_top_instance *nss_top = &nss_top_main;
303 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
304 struct nss_ipv6_msg nim;
305 struct nss_ipv6_rule_conn_cfg_msg *nirccm;
306 nss_tx_status_t nss_tx_status;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800307 int ret = NSS_FAILURE;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700308 uint32_t sum_of_conn;
309
310 /*
311 * Acquiring semaphore
312 */
313 down(&i6cfgp.sem);
314
315 /*
316 * Take a snapshot of the current value
317 */
318 i6cfgp.current_value = nss_ipv6_conn_cfg;
319
320 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
321 if (ret || (!write)) {
322 up(&i6cfgp.sem);
323 return ret;
324 }
Vijay Dewangan9db18752014-09-15 16:25:01 -0700325
326 /*
327 * Specifications for input
328 * 1) The input should be power of 2.
329 * 2) Input for ipv4 and ipv6 sum togther should not exceed 8k
330 * 3) Min. value should be at leat 256 connections. This is the
331 * minimum connections we will support for each of them.
332 */
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700333 sum_of_conn = nss_ipv4_conn_cfg + nss_ipv6_conn_cfg;
334 if ((nss_ipv6_conn_cfg & NSS_NUM_CONN_QUANTA_MASK) ||
335 (sum_of_conn > NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6) ||
336 (nss_ipv6_conn_cfg < NSS_MIN_NUM_CONN)) {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700337 nss_warning("%p: input supported connections (%d) does not adhere\
338 specifications\n1) not power of 2,\n2) is less than \
339 min val: %d, OR\n IPv4/6 total exceeds %d\n",
340 nss_ctx,
341 nss_ipv6_conn_cfg,
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700342 NSS_MIN_NUM_CONN,
343 NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6);
Stephen Wang06761022015-03-03 16:38:42 -0800344 goto failure;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700345 }
346
Vijay Dewangan9db18752014-09-15 16:25:01 -0700347
348 nss_info("%p: IPv6 supported connections: %d\n", nss_ctx, nss_ipv6_conn_cfg);
349
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700350 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_CFG_RULE_MSG,
351 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 -0700352
353 nirccm = &nim.msg.rule_conn_cfg;
354 nirccm->num_conn = htonl(nss_ipv6_conn_cfg);
355 nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
356
357 if (nss_tx_status != NSS_TX_SUCCESS) {
358 nss_warning("%p: nss_tx error setting IPv6 Connections: %d\n",
359 nss_ctx,
360 nss_ipv6_conn_cfg);
Stephen Wang06761022015-03-03 16:38:42 -0800361 goto failure;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700362 }
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700363
364 /*
365 * Blocking call, wait till we get ACK for this msg.
366 */
367 ret = wait_for_completion_timeout(&i6cfgp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
368 if (ret == 0) {
369 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
Stephen Wang06761022015-03-03 16:38:42 -0800370 goto failure;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700371 }
372
373 /*
374 * ACK/NACK received from NSS FW
375 * If ACK: Callback function will update nss_ipv4_conn_cfg with
376 * i6cfgp.num_conn_valid, which holds the user input
377 */
Vijay Dewangan488e5372014-12-29 21:40:11 -0800378 if (NSS_FAILURE == i6cfgp.response) {
Stephen Wang06761022015-03-03 16:38:42 -0800379 goto failure;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700380 }
381
382 up(&i6cfgp.sem);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800383 return NSS_SUCCESS;
Stephen Wang06761022015-03-03 16:38:42 -0800384
385failure:
386 /*
387 * Restore the current_value to its previous state
388 */
389 nss_ipv6_conn_cfg = i6cfgp.current_value;
390 up(&i6cfgp.sem);
391 return NSS_FAILURE;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700392}
393
394static ctl_table nss_ipv6_table[] = {
395 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700396 .procname = "ipv6_conn",
397 .data = &nss_ipv6_conn_cfg,
398 .maxlen = sizeof(int),
399 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700400 .proc_handler = &nss_ipv6_conn_cfg_handler,
401 },
402 { }
403};
404
405static ctl_table nss_ipv6_dir[] = {
406 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700407 .procname = "ipv6cfg",
408 .mode = 0555,
409 .child = nss_ipv6_table,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700410 },
411 { }
412};
413
414static ctl_table nss_ipv6_root_dir[] = {
415 {
416 .procname = "nss",
417 .mode = 0555,
418 .child = nss_ipv6_dir,
419 },
420 { }
421};
422
423static ctl_table nss_ipv6_root[] = {
424 {
425 .procname = "dev",
426 .mode = 0555,
427 .child = nss_ipv6_root_dir,
428 },
429 { }
430};
431
432static struct ctl_table_header *nss_ipv6_header;
433
434/*
435 * nss_ipv6_register_sysctl()
436 * Register sysctl specific to ipv4
437 */
438void nss_ipv6_register_sysctl(void)
439{
440 /*
441 * Register sysctl table.
442 */
443 nss_ipv6_header = register_sysctl_table(nss_ipv6_root);
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700444 sema_init(&i6cfgp.sem, 1);
445 init_completion(&i6cfgp.complete);
446 i6cfgp.current_value = nss_ipv6_conn_cfg;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700447}
448
449/*
450 * nss_ipv6_unregister_sysctl()
451 * Unregister sysctl specific to ipv4
452 */
453void nss_ipv6_unregister_sysctl(void)
454{
455 /*
456 * Unregister sysctl table.
457 */
458 if (nss_ipv6_header) {
459 unregister_sysctl_table(nss_ipv6_header);
460 }
461}
462
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700463/*
464 * nss_ipv6_msg_init()
465 * Initialize IPv6 message.
466 */
467void nss_ipv6_msg_init(struct nss_ipv6_msg *nim, uint16_t if_num, uint32_t type, uint32_t len,
468 nss_ipv6_msg_callback_t *cb, void *app_data)
469{
470 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
471}
472
Sol Kavy879eb8b2014-04-07 19:11:31 -0700473EXPORT_SYMBOL(nss_ipv6_tx);
474EXPORT_SYMBOL(nss_ipv6_notify_register);
475EXPORT_SYMBOL(nss_ipv6_notify_unregister);
476EXPORT_SYMBOL(nss_ipv6_get_mgr);
477EXPORT_SYMBOL(nss_ipv6_register_handler);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700478EXPORT_SYMBOL(nss_ipv6_register_sysctl);
479EXPORT_SYMBOL(nss_ipv6_unregister_sysctl);
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700480EXPORT_SYMBOL(nss_ipv6_msg_init);