Bharath M Kumar | 0d87e91 | 2013-08-12 18:32:57 +0530 | [diff] [blame] | 1 | /* |
| 2 | ************************************************************************** |
Zac Livingston | 866b0e2 | 2013-10-23 18:14:17 -0600 | [diff] [blame] | 3 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. |
Bharath M Kumar | 0d87e91 | 2013-08-12 18:32:57 +0530 | [diff] [blame] | 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_tun6rd.c |
| 19 | * |
| 20 | * This file is the NSS 6rd tunnel module |
| 21 | * ------------------------REVISION HISTORY----------------------------- |
| 22 | * Qualcomm Atheros 15/sep/2013 Created |
| 23 | */ |
| 24 | |
| 25 | #include <linux/types.h> |
| 26 | #include <linux/ip.h> |
| 27 | #include <linux/tcp.h> |
| 28 | #include <linux/module.h> |
| 29 | #include <linux/skbuff.h> |
| 30 | #include <net/ipv6.h> |
| 31 | #include <net/ipip.h> |
| 32 | #include <linux/if_arp.h> |
| 33 | #include "nss_api_if.h" |
| 34 | #include "nss_hlos_if.h" |
| 35 | |
| 36 | #define NSS_TUNRD_IF_NUMBER 10 |
| 37 | |
| 38 | /* |
| 39 | * NSS tun6rd debug macros |
| 40 | */ |
| 41 | #if (NSS_TUN6RD_DEBUG_LEVEL < 1) |
| 42 | #define nss_tun6rd_assert(fmt, args...) |
| 43 | #else |
| 44 | #define nss_tun6d_assert(c) if (!(c)) { BUG_ON(!(c)); } |
| 45 | #endif |
| 46 | |
| 47 | #if (NSS_TUN6RD_DEBUG_LEVEL < 2) |
| 48 | #define nss_tun6rd_error(fmt, args...) |
| 49 | #else |
| 50 | #define nss_tun6rd_error(fmt, args...) printk(KERN_WARNING "nss tun6rd:"fmt, ##args) |
| 51 | #endif |
| 52 | |
| 53 | #if (NSS_TUN6RD_DEBUG_LEVEL < 3) |
| 54 | #define nss_tun6rd_warning(fmt, args...) |
| 55 | #else |
| 56 | #define nss_tun6rd_warning(fmt, args...) printk(KERN_WARNING "nss tun6rd:"fmt, ##args) |
| 57 | #endif |
| 58 | |
| 59 | #if (NSS_TUN6RD_DEBUG_LEVEL < 4) |
| 60 | #define nss_tun6rd_info(fmt, args...) |
| 61 | #else |
| 62 | #define nss_tun6rd_info(fmt, args...) printk(KERN_INFO "nss tun6rd :"fmt, ##args) |
| 63 | #endif |
| 64 | |
| 65 | #if (NSS_TUN6RD_DEBUG_LEVEL < 5) |
| 66 | #define nss_tun6rd_trace(fmt, args...) |
| 67 | #else |
| 68 | #define nss_tun6rd_trace(fmt, args...) printk(KERN_DEBUG "nss tun6rd :"fmt, ##args) |
| 69 | #endif |
| 70 | |
| 71 | void nss_tun6rd_exception(void *ctx, void *buf); |
Radhakrishna Jiguru | 5ad493d | 2013-11-25 20:17:54 +0530 | [diff] [blame^] | 72 | void nss_tun6rd_event_receive(void *ctx, nss_tun6rd_event_t ev_type, |
| 73 | void *os_buf, uint32_t len); |
Bharath M Kumar | 0d87e91 | 2013-08-12 18:32:57 +0530 | [diff] [blame] | 74 | |
| 75 | enum tun6rd_metadata_types { |
| 76 | TUN6RD_METADATA_TYPE_IF_UP, |
| 77 | TUN6RD_METADATA_TYPE_IF_DOWN |
| 78 | }; |
| 79 | |
| 80 | /* |
| 81 | * 6rd configuration command structure |
| 82 | */ |
| 83 | struct nss_tunnel_6rd_cfg{ |
| 84 | uint32_t prefix[4]; /*6rd prefix */ |
| 85 | uint32_t relay_prefix; /* Relay prefix */ |
| 86 | uint16_t prefixlen; /* 6rd prefix len */ |
| 87 | uint16_t relay_prefixlen; /* Relay prefix length*/ |
| 88 | uint32_t saddr; /* Tunnel source address */ |
| 89 | uint32_t daddr; /* Tunnel destination addresss */ |
| 90 | uint8_t tos; /* Tunnel tos field */ |
| 91 | uint8_t ttl; /* Tunnel ttl field */ |
| 92 | |
| 93 | }; |
| 94 | |
| 95 | /* |
| 96 | * 6rd tunnel interface down command structure |
| 97 | */ |
| 98 | struct tun6rd_if_down_param{ |
| 99 | uint32_t prefix[4]; /*Tunnel 6rd prefix */ |
| 100 | }; |
| 101 | |
| 102 | /* |
| 103 | * 6rd Tunnel generic param |
| 104 | */ |
| 105 | struct nss_tunnel_6rd_param { |
| 106 | enum tun6rd_metadata_types type; |
| 107 | union { |
| 108 | struct nss_tunnel_6rd_cfg cfg; |
| 109 | struct tun6rd_if_down_param ifdown_param; |
| 110 | }sub; |
| 111 | }; |
| 112 | |
| 113 | /* |
| 114 | * 6rd tunnel host instance |
| 115 | */ |
| 116 | struct nss_tun6rd_tunnel{ |
| 117 | void *nss_ctx; |
| 118 | uint32_t if_num; |
| 119 | struct net_device *netdev; |
| 120 | uint32_t device_up; |
| 121 | }; |
| 122 | |
Radhakrishna Jiguru | 5ad493d | 2013-11-25 20:17:54 +0530 | [diff] [blame^] | 123 | /* |
| 124 | * 6rd tunnel stats |
| 125 | */ |
| 126 | struct nss_tun6rd_stats{ |
| 127 | uint32_t rx_packets; |
| 128 | uint32_t rx_bytes; |
| 129 | uint32_t tx_packets; |
| 130 | uint32_t tx_bytes; |
| 131 | }; |
| 132 | |
Bharath M Kumar | 0d87e91 | 2013-08-12 18:32:57 +0530 | [diff] [blame] | 133 | struct nss_tun6rd_tunnel g_tun6rd; |
| 134 | |
| 135 | /* |
| 136 | * Internal function |
| 137 | */ |
| 138 | static int |
| 139 | nss_tun6rd_dev_event(struct notifier_block *nb, |
| 140 | unsigned long event, |
| 141 | void *dev); |
| 142 | |
| 143 | /* |
| 144 | * Linux Net device Notifier |
| 145 | */ |
| 146 | struct notifier_block nss_tun6rd_notifier = { |
| 147 | .notifier_call = nss_tun6rd_dev_event, |
| 148 | }; |
| 149 | |
| 150 | /* |
| 151 | * nss_tun6rd_dev_up() |
| 152 | * 6RD Tunnel device i/f up handler |
| 153 | */ |
| 154 | void nss_tun6rd_dev_up( struct net_device * netdev) |
| 155 | { |
| 156 | struct ip_tunnel *tunnel; |
| 157 | struct ip_tunnel_6rd_parm *ip6rd; |
| 158 | const struct iphdr *tiph; |
| 159 | struct nss_tunnel_6rd_param tun6rdparam; |
| 160 | struct nss_tunnel_6rd_cfg *tun6rdcfg; |
| 161 | nss_tx_status_t status; |
| 162 | |
| 163 | /* |
| 164 | * Validate netdev for ipv6-in-ipv4 Tunnel |
| 165 | */ |
| 166 | if (netdev->type != ARPHRD_SIT ) { |
| 167 | return; |
| 168 | } |
| 169 | |
| 170 | tunnel = (struct ip_tunnel*)netdev_priv(netdev); |
| 171 | ip6rd = &tunnel->ip6rd; |
| 172 | |
| 173 | /* |
| 174 | * Valid 6rd Tunnel Check |
| 175 | * 1. 6rd Prefix len should be non zero |
| 176 | * 2. Relay prefix length should not be greater then 32 |
| 177 | * 3. To allow for stateless address auto-configuration on the CE LAN side, |
| 178 | * 6rd delegated prefix SHOULD be /64 or shorter. |
| 179 | */ |
| 180 | if ((ip6rd->prefixlen == 0 ) |
| 181 | || (ip6rd->relay_prefixlen > 32) |
| 182 | || (ip6rd->prefixlen |
| 183 | + (32 - ip6rd->relay_prefixlen) > 64)){ |
| 184 | |
| 185 | nss_tun6rd_error("Invalid 6rd argument prefix len %d \ |
| 186 | relayprefix len %d \n", |
| 187 | ip6rd->prefixlen,ip6rd->relay_prefixlen); |
| 188 | return; |
| 189 | } |
| 190 | |
| 191 | nss_tun6rd_info(" Valid 6rd Tunnel Prefix %x %x %x %x \n \ |
| 192 | prefix len %d relay_prefix %d relay_prefixlen %d \n", |
| 193 | ip6rd->prefix.s6_addr32[0],ip6rd->prefix.s6_addr32[1], |
| 194 | ip6rd->prefix.s6_addr32[2],ip6rd->prefix.s6_addr32[3], |
| 195 | ip6rd->prefixlen, ip6rd->relay_prefix, |
| 196 | ip6rd->relay_prefixlen); |
| 197 | |
| 198 | /* |
| 199 | * Prepare The Tunnel configuration parameter to send to nss |
| 200 | */ |
| 201 | memset( &tun6rdparam, 0, sizeof(struct nss_tunnel_6rd_param)); |
| 202 | tun6rdparam.type = TUN6RD_METADATA_TYPE_IF_UP; |
| 203 | tun6rdcfg = (struct nss_tunnel_6rd_cfg *)&tun6rdparam.sub.cfg; |
| 204 | |
| 205 | /* |
| 206 | * Find the Tunnel device ipHeader info |
| 207 | */ |
| 208 | tiph = &tunnel->parms.iph ; |
| 209 | nss_tun6rd_trace(" Tunnel Param srcaddr %x daddr %x ttl %d tos %x\n", |
| 210 | tiph->saddr, tiph->daddr,tiph->ttl,tiph->tos); |
| 211 | |
| 212 | if(tiph->saddr == 0) { |
| 213 | nss_tun6rd_error("Tunnel src address not configured %x\n", |
| 214 | tiph->saddr); |
| 215 | return; |
| 216 | } |
| 217 | |
| 218 | if (tiph->daddr == 0) { |
| 219 | nss_tun6rd_error("Tunnel dest address not configured %x\n", |
| 220 | tiph->daddr); |
| 221 | return; |
| 222 | } |
| 223 | |
| 224 | tun6rdcfg->prefixlen = ip6rd->prefixlen; |
| 225 | tun6rdcfg->relay_prefix = ip6rd->relay_prefix; |
| 226 | tun6rdcfg->relay_prefixlen = ip6rd->relay_prefixlen; |
| 227 | tun6rdcfg->saddr = ntohl(tiph->saddr); |
| 228 | tun6rdcfg->daddr = ntohl(tiph->daddr); |
| 229 | tun6rdcfg->prefix[0] = ntohl(ip6rd->prefix.s6_addr32[0]); |
| 230 | tun6rdcfg->prefix[1] = ntohl(ip6rd->prefix.s6_addr32[1]); |
| 231 | tun6rdcfg->prefix[2] = ntohl(ip6rd->prefix.s6_addr32[2]); |
| 232 | tun6rdcfg->prefix[3] = ntohl(ip6rd->prefix.s6_addr32[3]); |
| 233 | tun6rdcfg->ttl = tiph->ttl; |
| 234 | tun6rdcfg->tos = tiph->tos; |
| 235 | |
| 236 | nss_tun6rd_trace(" 6rd Tunnel info \n"); |
| 237 | nss_tun6rd_trace(" saddr %x daddr %d ttl %x tos %x \n", |
| 238 | tiph->saddr, tiph->daddr, tiph->ttl, tiph->tos); |
| 239 | nss_tun6rd_trace(" Prefix %x:%x:%x:%x Prefix len %d \n", |
| 240 | ip6rd->prefix.s6_addr32[0], ip6rd->prefix.s6_addr32[1], |
| 241 | ip6rd->prefix.s6_addr32[2], ip6rd->prefix.s6_addr32[3], |
| 242 | ip6rd->prefixlen); |
| 243 | nss_tun6rd_trace("Relay Prefix %x Len %d\n", |
| 244 | ip6rd->relay_prefix, ip6rd->relay_prefixlen); |
| 245 | |
| 246 | /* |
| 247 | * Register 6rd tunnel with NSS |
| 248 | */ |
| 249 | g_tun6rd.nss_ctx = nss_register_tun6rd_if(g_tun6rd.if_num, |
| 250 | nss_tun6rd_exception, |
Radhakrishna Jiguru | 5ad493d | 2013-11-25 20:17:54 +0530 | [diff] [blame^] | 251 | nss_tun6rd_event_receive, |
Bharath M Kumar | 0d87e91 | 2013-08-12 18:32:57 +0530 | [diff] [blame] | 252 | netdev); |
| 253 | if (g_tun6rd.nss_ctx == NULL) { |
| 254 | nss_tun6rd_trace("nss_register_tun6rd_if Failed \n"); |
| 255 | return; |
| 256 | } else { |
| 257 | nss_tun6rd_trace("nss_register_tun6rd_if Success \n"); |
| 258 | } |
| 259 | |
| 260 | nss_tun6rd_trace("Sending 6rd tunnel i/f up command to NSS %x \n", |
| 261 | (int)g_tun6rd.nss_ctx); |
| 262 | |
| 263 | /* |
| 264 | * Send 6rd Tunnel UP command to NSS |
| 265 | */ |
| 266 | status = nss_tx_generic_if_buf(g_tun6rd.nss_ctx, |
| 267 | g_tun6rd.if_num, |
Radhakrishna Jiguru | 5ad493d | 2013-11-25 20:17:54 +0530 | [diff] [blame^] | 268 | (uint8_t *)&tun6rdparam, |
Bharath M Kumar | 0d87e91 | 2013-08-12 18:32:57 +0530 | [diff] [blame] | 269 | sizeof(struct nss_tunnel_6rd_param)); |
| 270 | |
| 271 | if (status != NSS_TX_SUCCESS) { |
| 272 | nss_tun6rd_error("Tunnel up command error %d \n", status); |
| 273 | return; |
| 274 | } |
| 275 | |
| 276 | g_tun6rd.device_up = 1; |
| 277 | } |
| 278 | |
| 279 | /* |
| 280 | * nss_tun6rd_dev_down() |
| 281 | * 6RD Tunnel device i/f down handler |
| 282 | */ |
| 283 | void nss_tun6rd_dev_down( struct net_device * netdev) |
| 284 | { |
| 285 | struct ip_tunnel *tunnel; |
| 286 | struct ip_tunnel_6rd_parm *ip6rd; |
| 287 | struct nss_tunnel_6rd_param tun6rdparam; |
| 288 | struct tun6rd_if_down_param *ifdown; |
| 289 | nss_tx_status_t status; |
| 290 | |
| 291 | /* |
| 292 | * Check if tunnel 6rd is registered ? |
| 293 | */ |
| 294 | if (g_tun6rd.nss_ctx == NULL) { |
| 295 | return; |
| 296 | } |
| 297 | |
| 298 | /* |
| 299 | * Validate netdev for ipv6-in-ipv4 Tunnel |
| 300 | */ |
| 301 | if (netdev->type != ARPHRD_SIT ) { |
| 302 | return; |
| 303 | } |
| 304 | |
| 305 | tunnel = (struct ip_tunnel*)netdev_priv(netdev); |
| 306 | ip6rd = &tunnel->ip6rd; |
| 307 | |
| 308 | /* |
| 309 | * Valid 6rd Tunnel Check |
| 310 | */ |
| 311 | if ((ip6rd->prefixlen == 0 ) |
| 312 | || (ip6rd->relay_prefixlen > 32 ) |
| 313 | || (ip6rd->prefixlen |
| 314 | + (32 - ip6rd->relay_prefixlen) > 64)){ |
| 315 | |
| 316 | nss_tun6rd_error("Invalid 6rd argument prefix len %d \ |
| 317 | relayprefix len %d \n", |
| 318 | ip6rd->prefixlen,ip6rd->relay_prefixlen); |
| 319 | return; |
| 320 | } |
| 321 | |
| 322 | memset( &tun6rdparam, 0, sizeof(struct nss_tunnel_6rd_param)); |
| 323 | tun6rdparam.type = TUN6RD_METADATA_TYPE_IF_DOWN; |
| 324 | ifdown = (struct tun6rd_if_down_param *)&tun6rdparam.sub.ifdown_param; |
| 325 | ifdown->prefix[0] = ntohl(ip6rd->prefix.s6_addr32[0]); |
| 326 | ifdown->prefix[1] = ntohl(ip6rd->prefix.s6_addr32[1]); |
| 327 | ifdown->prefix[2] = ntohl(ip6rd->prefix.s6_addr32[2]); |
| 328 | ifdown->prefix[3] = ntohl(ip6rd->prefix.s6_addr32[3]); |
| 329 | |
| 330 | nss_tun6rd_trace(" Prefix %x:%x:%x:%x Prefix len %d \n", |
| 331 | ip6rd->prefix.s6_addr32[0], ip6rd->prefix.s6_addr32[1], |
| 332 | ip6rd->prefix.s6_addr32[2], ip6rd->prefix.s6_addr32[3], |
| 333 | ip6rd->prefixlen); |
| 334 | |
| 335 | |
| 336 | nss_tun6rd_trace("Sending Tunnle 6rd Down command %x \n",g_tun6rd.if_num); |
| 337 | status = nss_tx_generic_if_buf(g_tun6rd.nss_ctx, |
| 338 | g_tun6rd.if_num, |
| 339 | (uint8_t *)&tun6rdparam, |
| 340 | sizeof(struct nss_tunnel_6rd_param)); |
| 341 | |
| 342 | if (status != NSS_TX_SUCCESS) { |
| 343 | nss_tun6rd_error("Tunnel down command error %d \n", status); |
| 344 | return; |
| 345 | } |
| 346 | |
| 347 | /* |
| 348 | * Un-Register 6rd tunnel with NSS |
| 349 | */ |
| 350 | nss_unregister_tun6rd_if(g_tun6rd.if_num); |
| 351 | g_tun6rd.nss_ctx = NULL; |
| 352 | g_tun6rd.device_up = 0; |
| 353 | return; |
| 354 | } |
| 355 | |
| 356 | /* |
| 357 | * nss_tun6rd_dev_event() |
| 358 | * Net device notifier for 6rd module |
| 359 | */ |
| 360 | static int nss_tun6rd_dev_event(struct notifier_block *nb, |
| 361 | unsigned long event, void *dev) |
| 362 | { |
| 363 | struct net_device *netdev = (struct net_device *)dev; |
| 364 | |
| 365 | nss_tun6rd_trace("%s\n",__FUNCTION__); |
| 366 | switch (event) { |
| 367 | case NETDEV_UP: |
| 368 | nss_tun6rd_trace(" NETDEV_UP :event %lu name %s \n", |
| 369 | event,netdev->name); |
| 370 | nss_tun6rd_dev_up(netdev); |
| 371 | break; |
| 372 | |
| 373 | case NETDEV_DOWN: |
| 374 | nss_tun6rd_trace(" NETDEV_DOWN :event %lu name %s \n", |
| 375 | event,netdev->name); |
| 376 | nss_tun6rd_dev_down(netdev); |
| 377 | break; |
| 378 | |
| 379 | default: |
| 380 | nss_tun6rd_trace("Unhandled notifier dev %s event %x \n", |
| 381 | netdev->name,(int)event); |
| 382 | break; |
| 383 | } |
| 384 | |
| 385 | return NOTIFY_DONE; |
| 386 | } |
| 387 | |
| 388 | /* |
| 389 | * nss_tun6rd_exception() |
| 390 | * Exception handler registered to NSS driver |
| 391 | */ |
| 392 | void nss_tun6rd_exception(void *ctx, void *buf) |
| 393 | { |
| 394 | struct net_device *dev = (struct net_device *)ctx; |
| 395 | struct sk_buff *skb = (struct sk_buff *)buf; |
| 396 | const struct iphdr *iph; |
| 397 | |
| 398 | skb->dev = dev; |
| 399 | nss_tun6rd_info("received - %d bytes name %s ver %x \n", |
| 400 | skb->len,dev->name,skb->data[0]); |
| 401 | |
| 402 | iph = (const struct iphdr *)skb->data; |
| 403 | |
| 404 | /* |
| 405 | * Packet after Decap/Encap Did not find the Rule. |
| 406 | */ |
| 407 | if (iph->version == 4) { |
| 408 | skb->protocol = htons(ETH_P_IP); |
| 409 | } else { |
| 410 | skb->protocol = htons(ETH_P_IPV6); |
| 411 | } |
| 412 | |
| 413 | skb_reset_network_header(skb); |
| 414 | skb->pkt_type = PACKET_HOST; |
| 415 | skb->skb_iif = dev->ifindex; |
| 416 | skb->ip_summed = CHECKSUM_NONE; |
| 417 | netif_receive_skb(skb); |
| 418 | } |
| 419 | |
| 420 | /* |
Radhakrishna Jiguru | 5ad493d | 2013-11-25 20:17:54 +0530 | [diff] [blame^] | 421 | * nss_tun6rd_update_dev_stats |
| 422 | * Update the Dev stats received from NetAp |
| 423 | */ |
| 424 | static void nss_tun6rd_update_dev_stats(struct net_device *dev, |
| 425 | struct nss_tun6rd_stats_sync *tun6rdstats) |
| 426 | { |
| 427 | void *ptr; |
| 428 | struct nss_tun6rd_stats stats; |
| 429 | |
| 430 | stats.rx_packets = tun6rdstats->rx_packets; |
| 431 | stats.rx_bytes = tun6rdstats->rx_bytes; |
| 432 | stats.tx_packets = tun6rdstats->tx_packets; |
| 433 | stats.tx_bytes = tun6rdstats->tx_bytes; |
| 434 | ptr = (void *)&stats; |
| 435 | ipip6_update_offload_stats(dev, ptr); |
| 436 | } |
| 437 | |
| 438 | /** |
| 439 | * @brief Event Callback to receive events from NSS |
| 440 | * @param[in] pointer to net device context |
| 441 | * @param[in] event type |
| 442 | * @param[in] pointer to buffer |
| 443 | * @param[in] length of buffer |
| 444 | * @return Returns void |
| 445 | */ |
| 446 | void nss_tun6rd_event_receive(void *if_ctx, nss_tun6rd_event_t ev_type, |
| 447 | void *os_buf, uint32_t len) |
| 448 | { |
| 449 | struct net_device *netdev = NULL; |
| 450 | netdev = (struct net_device *)if_ctx; |
| 451 | |
| 452 | switch (ev_type) { |
| 453 | case NSS_TUN6RD_EVENT_STATS: |
| 454 | nss_tun6rd_update_dev_stats(netdev, (struct nss_tun6rd_stats_sync *)os_buf ); |
| 455 | break; |
| 456 | |
| 457 | default: |
| 458 | nss_tun6rd_info("%s: Unknown Event from NSS", |
| 459 | __FUNCTION__); |
| 460 | break; |
| 461 | } |
| 462 | } |
| 463 | |
| 464 | /* |
Bharath M Kumar | 0d87e91 | 2013-08-12 18:32:57 +0530 | [diff] [blame] | 465 | * nss_tun6rd_init_module() |
| 466 | * Tunnel 6rd module init function |
| 467 | */ |
| 468 | int __init nss_tun6rd_init_module(void) |
| 469 | { |
| 470 | nss_tun6rd_info("module (platform - IPQ806x , Build - %s:%s) loaded\n", |
| 471 | __DATE__, __TIME__); |
| 472 | |
| 473 | register_netdevice_notifier(&nss_tun6rd_notifier); |
| 474 | nss_tun6rd_trace("Netdev Notifier registerd \n"); |
| 475 | |
| 476 | g_tun6rd.if_num = NSS_TUNRD_IF_NUMBER; |
| 477 | g_tun6rd.netdev = NULL; |
| 478 | g_tun6rd.device_up = 0; |
| 479 | g_tun6rd.nss_ctx = NULL; |
| 480 | |
| 481 | return 0; |
| 482 | } |
| 483 | |
| 484 | /* |
| 485 | * nss_tun6rd_exit_module() |
| 486 | * Tunnel 6rd module exit function |
| 487 | */ |
| 488 | void __exit nss_tun6rd_exit_module(void) |
| 489 | { |
| 490 | |
| 491 | unregister_netdevice_notifier(&nss_tun6rd_notifier); |
| 492 | nss_tun6rd_info("module unloaded\n"); |
| 493 | } |
| 494 | |
| 495 | module_init(nss_tun6rd_init_module); |
| 496 | module_exit(nss_tun6rd_exit_module); |
| 497 | |
| 498 | MODULE_LICENSE("Dual BSD/GPL"); |
| 499 | MODULE_DESCRIPTION("NSS tun6rd offload manager"); |