Merge "[qca-nss-drv] add supporting multi-tun6rd interface"
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index f6698e9..9d34dbb 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -75,7 +75,7 @@
#define NSS_MAX_VIRTUAL_INTERFACES 16
#define NSS_MAX_TUNNEL_INTERFACES 4
#define NSS_MAX_SPECIAL_INTERFACES 24
-#define NSS_MAX_DYNAMIC_INTERFACES 3
+#define NSS_MAX_DYNAMIC_INTERFACES 8
/**
* Start of individual interface groups
diff --git a/exports/nss_dynamic_interface.h b/exports/nss_dynamic_interface.h
index c82a3b3..79d8582 100644
--- a/exports/nss_dynamic_interface.h
+++ b/exports/nss_dynamic_interface.h
@@ -29,6 +29,7 @@
NSS_DYNAMIC_INTERFACE_TYPE_NONE = 0,
NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR = 1, /* GRE_REDIR Interface type */
NSS_DYNAMIC_INTERFACE_TYPE_CAPVAPV1 = 2, /* CAPVAPV1 Interface type */
+ NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD = 3, /* TUN6RD Interface type */
NSS_DYNAMIC_INTERFACE_TYPE_MAX
};
@@ -51,4 +52,13 @@
*/
extern nss_tx_status_t nss_dynamic_interface_dealloc_node(int if_num, enum nss_dynamic_interface_type type);
+/**
+ * @brief The inferface number belong to the dynamic interface
+ *
+ * @param if_num interface number of dynamic interface
+ *
+ * @return bool true or false
+ */
+bool nss_is_dynamic_interface(int if_num);
+
#endif /* __NSS_DYNAMIC_INTERFACE_H*/
diff --git a/exports/nss_tun6rd.h b/exports/nss_tun6rd.h
index cf58fa1..98b9bea 100644
--- a/exports/nss_tun6rd.h
+++ b/exports/nss_tun6rd.h
@@ -30,50 +30,51 @@
* 6rd tunnel request/response types
*/
enum nss_tun6rd_metadata_types {
- NSS_TUN6RD_TX_IF_CREATE,
- NSS_TUN6RD_TX_IF_DESTROY,
+ NSS_TUN6RD_ATTACH_PNODE,
NSS_TUN6RD_RX_STATS_SYNC,
+ NSS_TUN6RD_ADD_UPDATE_PEER,
NSS_TUN6RD_MAX,
};
/**
* 6rd tunnel configuration message structure
*/
-struct nss_tun6rd_create_msg {
- uint32_t prefix[4]; /* 6rd prefix */
- uint32_t relay_prefix; /* Relay prefix */
- uint16_t prefixlen; /* 6rd prefix len */
- uint16_t relay_prefixlen;/* Relay prefix length*/
+struct nss_tun6rd_attach_tunnel_msg {
+ uint32_t prefix[4]; /* 6rd prefix */
+ uint32_t relay_prefix; /* Relay prefix */
+ uint16_t prefixlen; /* 6rd prefix len */
+ uint16_t relay_prefixlen; /* Relay prefix length*/
uint32_t saddr; /* Tunnel source address */
uint32_t daddr; /* Tunnel destination addresss */
- uint8_t tos; /* Tunnel tos field */
- uint8_t ttl; /* Tunnel ttl field */
- uint16_t reserved; /* Reserved field */
-};
-
-/**
- * 6rd tunnel interface down message structure
- */
-struct nss_tun6rd_destroy_msg {
- uint32_t prefix[4]; /* Place holder */
+ uint8_t tos; /* Tunnel tos field */
+ uint8_t ttl; /* Tunnel ttl field */
+ uint16_t reserved; /* Reserved field */
};
/**
* 6rd tunnel statistics sync message structure.
*/
-struct nss_tun6rd_stats_sync_msg {
- struct nss_cmn_node_stats node_stats;
+struct nss_tun6rd_sync_stats_msg {
+ struct nss_cmn_node_stats node_stats; /* Node statstics*/
+};
+
+/**
+ * 6rd tunnel peer addr.
+ */
+struct nss_tun6rd_set_peer_msg {
+ uint32_t ipv6_address[4]; /* The peer's ipv6 addr*/
+ uint32_t dest; /* The peer's ipv4 addr*/
};
/**
* Message structure to send/receive 6rd tunnel messages
*/
struct nss_tun6rd_msg {
- struct nss_cmn_msg cm; /* Message Header */
+ struct nss_cmn_msg cm; /* Message Header */
union {
- struct nss_tun6rd_create_msg tun6rd_create; /* Message: Create 6rd tunnel */
- struct nss_tun6rd_destroy_msg tun6rd_destroy; /* Message: Destroy 6rd tunnel */
- struct nss_tun6rd_stats_sync_msg stats_sync; /* Message: interface stats sync */
+ struct nss_tun6rd_attach_tunnel_msg tunnel; /* Message: Attach 6rd tunnel */
+ struct nss_tun6rd_sync_stats_msg stats; /* Message: interface stats sync */
+ struct nss_tun6rd_set_peer_msg peer; /* Message: add/update peer */
} msg;
};
@@ -98,10 +99,17 @@
extern nss_tx_status_t nss_tun6rd_tx(struct nss_ctx_instance *nss_ctx, struct nss_tun6rd_msg *msg);
/**
+ * @brief Get the tun6rd context used in the nss_tun6rd_tx
+ *
+ * @return struct nss_ctx_instance *NSS context
+ */
+extern struct nss_ctx_instance *nss_tun6rd_get_context(void);
+
+/**
* @brief Callback to receive 6rd tunnel data
*
* @param app_data Application context of the message
- * @param os_buf Pointer to data buffer
+ * @param os_buf Pointer to data buffer
*
* @return void
*/
@@ -118,7 +126,7 @@
* @return nss_ctx_instance* NSS context
*/
extern struct nss_ctx_instance *nss_register_tun6rd_if(uint32_t if_num, nss_tun6rd_callback_t tun6rd_callback,
- nss_tun6rd_msg_callback_t msg_callback, struct net_device *netdev);
+ nss_tun6rd_msg_callback_t msg_callback, struct net_device *netdev);
/**
* @brief Unregister 6rd tunnel interface with NSS
diff --git a/nss_connmgr_tun6rd.c b/nss_connmgr_tun6rd.c
index 2a52087..801dc43 100644
--- a/nss_connmgr_tun6rd.c
+++ b/nss_connmgr_tun6rd.c
@@ -31,6 +31,7 @@
#include <net/ipip.h>
#include <linux/if_arp.h>
#include <nss_api_if.h>
+#include <nss_dynamic_interface.h>
/*
* NSS tun6rd debug macros
@@ -38,46 +39,40 @@
#if (NSS_TUN6RD_DEBUG_LEVEL < 1)
#define nss_tun6rd_assert(fmt, args...)
#else
-#define nss_tun6d_assert(c) if (!(c)) { BUG_ON(!(c)); }
+#define nss_tun6rd_assert(c) if (!(c)) { BUG_ON(!(c)); }
#endif
-#if (NSS_TUN6RD_DEBUG_LEVEL < 2)
-#define nss_tun6rd_error(fmt, args...)
+#if defined(CONFIG_DYNAMIC_DEBUG)
+/*
+ * Compile messages for dynamic enable/disable
+ */
+#define nss_tun6rd_warning(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define nss_tun6rd_info(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define nss_tun6rd_trace(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
-#define nss_tun6rd_error(fmt, args...) printk(KERN_WARNING "nss tun6rd:"fmt, ##args)
+
+/*
+ * Statically compile messages at different levels
+ */
+#if (NSS_TUN6RD_DEBUG_LEVEL < 2)
+#define nss_tun6rd_warning(s, ...)
+#else
+#define nss_tun6rd_warning(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
#if (NSS_TUN6RD_DEBUG_LEVEL < 3)
-#define nss_tun6rd_warning(fmt, args...)
+#define nss_tun6rd_info(s, ...)
#else
-#define nss_tun6rd_warning(fmt, args...) printk(KERN_WARNING "nss tun6rd:"fmt, ##args)
+#define nss_tun6rd_info(s, ...) pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
#if (NSS_TUN6RD_DEBUG_LEVEL < 4)
-#define nss_tun6rd_info(fmt, args...)
+#define nss_tun6rd_trace(s, ...)
#else
-#define nss_tun6rd_info(fmt, args...) printk(KERN_INFO "nss tun6rd :"fmt, ##args)
+#define nss_tun6rd_trace(s, ...) pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
-
-#if (NSS_TUN6RD_DEBUG_LEVEL < 5)
-#define nss_tun6rd_trace(fmt, args...)
-#else
-#define nss_tun6rd_trace(fmt, args...) printk(KERN_DEBUG "nss tun6rd :"fmt, ##args)
#endif
-void nss_tun6rd_exception(void *ctx, void *buf, __attribute__((unused)) struct napi_struct *napi);
-void nss_tun6rd_event_receive(void *ctx, struct nss_tun6rd_msg *msg);
-
-/*
- * 6rd tunnel host instance
- */
-struct nss_tun6rd_tunnel{
- struct nss_ctx_instance *nss_ctx;
- uint32_t if_num;
- struct net_device *netdev;
- uint32_t device_up;
-};
-
/*
* 6rd tunnel stats
*/
@@ -88,45 +83,106 @@
uint32_t tx_bytes; /* Number of transmitted bytes */
};
+/*
+ * nss_tun6rd_update_dev_stats
+ * Update the Dev stats received from NetAp
+ */
+static void nss_tun6rd_update_dev_stats(struct net_device *dev,
+ struct nss_tun6rd_sync_stats_msg *sync_stats)
+{
+ struct nss_tun6rd_stats stats;
-struct nss_tun6rd_tunnel g_tun6rd;
+ stats.rx_packets = sync_stats->node_stats.rx_packets;
+ stats.rx_bytes = sync_stats->node_stats.rx_bytes;
+ stats.tx_packets = sync_stats->node_stats.tx_packets;
+ stats.tx_bytes = sync_stats->node_stats.tx_bytes;
+
+ ipip6_update_offload_stats(dev, (void *)&stats);
+}
/*
- * Internal function
+ * nss_tun6rd_event_receive()
+ * Event Callback to receive events from NSS
*/
-static int
-nss_tun6rd_dev_event(struct notifier_block *nb,
- unsigned long event,
- void *dev);
+static void nss_tun6rd_event_receive(void *if_ctx, struct nss_tun6rd_msg *tnlmsg)
+{
+ struct net_device *netdev = if_ctx;
+
+ switch (tnlmsg->cm.type) {
+ case NSS_TUN6RD_RX_STATS_SYNC:
+ nss_tun6rd_update_dev_stats(netdev, (struct nss_tun6rd_sync_stats_msg *)&tnlmsg->msg.stats);
+ break;
+
+ default:
+ nss_tun6rd_info("Unknown Event from NSS\n");
+ break;
+ }
+}
/*
- * Linux Net device Notifier
+ * nss_tun6rd_exception()
+ * Exception handler registered to NSS driver
*/
-struct notifier_block nss_tun6rd_notifier = {
- .notifier_call = nss_tun6rd_dev_event,
-};
+static void nss_tun6rd_exception(void *ctx, void *buf, __attribute__((unused)) struct napi_struct *napi)
+{
+ struct net_device *dev = (struct net_device *)ctx;
+ struct sk_buff *skb = (struct sk_buff *)buf;
+ const struct iphdr *iph;
+
+ skb->dev = dev;
+ nss_tun6rd_info("received - %d bytes name %s ver %x\n",
+ skb->len,dev->name,skb->data[0]);
+
+ iph = (const struct iphdr *)skb->data;
+
+ /*
+ * Packet after Decap/Encap Did not find the Rule.
+ */
+ if (iph->version != 4) {
+ skb->protocol = htons(ETH_P_IPV6);
+ } else {
+ if (iph->protocol == IPPROTO_IPV6) {
+ skb_pull(skb, sizeof(struct iphdr));
+ skb->protocol = htons(ETH_P_IPV6);
+ skb_reset_network_header(skb);
+ skb->pkt_type = PACKET_HOST;
+ skb->ip_summed = CHECKSUM_NONE;
+ dev_queue_xmit(skb);
+ return;
+ }
+ skb->protocol = htons(ETH_P_IP);
+ }
+
+ skb_reset_network_header(skb);
+ skb->pkt_type = PACKET_HOST;
+ skb->skb_iif = dev->ifindex;
+ skb->ip_summed = CHECKSUM_NONE;
+ netif_receive_skb(skb);
+}
/*
* nss_tun6rd_dev_up()
* 6RD Tunnel device i/f up handler
*/
-void nss_tun6rd_dev_up( struct net_device * netdev)
+static int nss_tun6rd_dev_up(struct net_device *netdev)
{
struct ip_tunnel *tunnel;
struct ip_tunnel_6rd_parm *ip6rd;
const struct iphdr *tiph;
struct nss_tun6rd_msg tun6rdmsg;
- struct nss_tun6rd_create_msg *tun6rdcfg;
+ struct nss_tun6rd_attach_tunnel_msg *tun6rdcfg;
+ uint32_t if_number;
nss_tx_status_t status;
+ struct nss_ctx_instance *nss_ctx;
/*
* Validate netdev for ipv6-in-ipv4 Tunnel
*/
- if (netdev->type != ARPHRD_SIT ) {
- return;
+ if (netdev->type != ARPHRD_SIT) {
+ return NOTIFY_BAD;
}
- tunnel = (struct ip_tunnel*)netdev_priv(netdev);
+ tunnel = (struct ip_tunnel *)netdev_priv(netdev);
ip6rd = &tunnel->ip6rd;
/*
@@ -139,16 +195,14 @@
if ((ip6rd->prefixlen == 0 )
|| (ip6rd->relay_prefixlen > 32)
|| (ip6rd->prefixlen
- + (32 - ip6rd->relay_prefixlen) > 64)){
+ + (32 - ip6rd->relay_prefixlen) > 64)) {
- nss_tun6rd_error("Invalid 6rd argument prefix len %d \
- relayprefix len %d \n",
+ nss_tun6rd_warning("Invalid 6rd argument prefix len %d relayprefix len %d \n",
ip6rd->prefixlen,ip6rd->relay_prefixlen);
- return;
+ return NOTIFY_BAD;
}
- nss_tun6rd_info(" Valid 6rd Tunnel Prefix %x %x %x %x \n \
- prefix len %d relay_prefix %d relay_prefixlen %d \n",
+ nss_tun6rd_info("Valid 6rd Tunnel Prefix %x %x %x %x\n Prefix len %d relay_prefix %d relay_prefixlen %d \n",
ip6rd->prefix.s6_addr32[0],ip6rd->prefix.s6_addr32[1],
ip6rd->prefix.s6_addr32[2],ip6rd->prefix.s6_addr32[3],
ip6rd->prefixlen, ip6rd->relay_prefix,
@@ -158,41 +212,42 @@
* Find the Tunnel device IP header info
*/
tiph = &tunnel->parms.iph ;
- nss_tun6rd_trace(" Tunnel Param srcaddr %x daddr %x ttl %d tos %x\n",
+ nss_tun6rd_trace("Tunnel Param srcaddr %x daddr %x ttl %d tos %x\n",
tiph->saddr, tiph->daddr,tiph->ttl,tiph->tos);
- if(tiph->saddr == 0) {
- nss_tun6rd_error("Tunnel src address not configured %x\n",
+ if (tiph->saddr == 0) {
+ nss_tun6rd_warning("Tunnel src address not configured %x\n",
tiph->saddr);
- return;
+ return NOTIFY_BAD;
}
- if (tiph->daddr == 0) {
- nss_tun6rd_error("Tunnel dest address not configured %x\n",
- tiph->daddr);
- return;
+ if_number = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD);
+ if (-1 == if_number) {
+ nss_tun6rd_warning("Request interface number failed\n");
+ return NOTIFY_BAD;
}
/*
* Register 6rd tunnel with NSS
*/
- g_tun6rd.nss_ctx = nss_register_tun6rd_if(g_tun6rd.if_num,
+ nss_ctx = nss_register_tun6rd_if(if_number,
nss_tun6rd_exception,
nss_tun6rd_event_receive,
netdev);
- if (g_tun6rd.nss_ctx == NULL) {
- nss_tun6rd_trace("nss_register_tun6rd_if Failed \n");
- return;
+ if (!nss_ctx) {
+ status = nss_dynamic_interface_dealloc_node(if_number, NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD);
+ if (status != NSS_TX_SUCCESS) {
+ nss_tun6rd_warning("Unable to dealloc the node[%d] in the NSS fw!\n", if_number);
+ }
+ nss_tun6rd_trace("nss_register_tun6rd_if failed \n");
+ return NOTIFY_BAD;
}
- nss_tun6rd_trace("nss_register_tun6rd_if Success \n");
-
/*
* Prepare The Tunnel configuration parameter to send to nss
*/
memset(&tun6rdmsg, 0, sizeof(struct nss_tun6rd_msg));
- tun6rdcfg = &tun6rdmsg.msg.tun6rd_create;
-
+ tun6rdcfg = &tun6rdmsg.msg.tunnel;
tun6rdcfg->prefixlen = ip6rd->prefixlen;
tun6rdcfg->relay_prefix = ip6rd->relay_prefix;
tun6rdcfg->relay_prefixlen = ip6rd->relay_prefixlen;
@@ -205,61 +260,68 @@
tun6rdcfg->ttl = tiph->ttl;
tun6rdcfg->tos = tiph->tos;
- nss_tun6rd_trace(" 6rd Tunnel info \n");
- nss_tun6rd_trace(" saddr %x daddr %d ttl %x tos %x \n",
+ nss_tun6rd_trace(" 6rd Tunnel info\n");
+ nss_tun6rd_trace(" saddr %x daddr %d ttl %x tos %x\n",
tiph->saddr, tiph->daddr, tiph->ttl, tiph->tos);
- nss_tun6rd_trace(" Prefix %x:%x:%x:%x Prefix len %d \n",
+ nss_tun6rd_trace(" Prefix %x:%x:%x:%x Prefix len %d\n",
ip6rd->prefix.s6_addr32[0], ip6rd->prefix.s6_addr32[1],
ip6rd->prefix.s6_addr32[2], ip6rd->prefix.s6_addr32[3],
ip6rd->prefixlen);
nss_tun6rd_trace("Relay Prefix %x Len %d\n",
ip6rd->relay_prefix, ip6rd->relay_prefixlen);
- nss_tun6rd_trace("Sending 6rd tunnel i/f up command to NSS %x \n",
- (int)g_tun6rd.nss_ctx);
+ nss_tun6rd_trace("Sending 6rd tunnel i/f up command to NSS %x\n",
+ (int)nss_ctx);
/*
* Send 6rd Tunnel UP command to NSS
*/
- nss_cmn_msg_init(&tun6rdmsg.cm, NSS_TUN6RD_INTERFACE, NSS_TUN6RD_TX_IF_CREATE,
- sizeof(struct nss_tun6rd_create_msg), NULL, NULL);
+ nss_cmn_msg_init(&tun6rdmsg.cm, if_number, NSS_TUN6RD_ATTACH_PNODE,
+ sizeof(struct nss_tun6rd_attach_tunnel_msg), NULL, NULL);
- status = nss_tun6rd_tx(g_tun6rd.nss_ctx, &tun6rdmsg);
+ status = nss_tun6rd_tx(nss_ctx, &tun6rdmsg);
if (status != NSS_TX_SUCCESS) {
- nss_tun6rd_error("Tunnel up command error %d \n", status);
- return;
+ nss_unregister_tun6rd_if(if_number);
+ status = nss_dynamic_interface_dealloc_node(if_number, NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD);
+ if (status != NSS_TX_SUCCESS) {
+ nss_tun6rd_warning("Unable to dealloc the node[%d] in the NSS fw!\n", if_number);
+ }
+ nss_tun6rd_warning("Tunnel up command error %d\n", status);
+ return NOTIFY_BAD;
}
- g_tun6rd.device_up = 1;
+ return NOTIFY_DONE;
}
/*
* nss_tun6rd_dev_down()
* 6RD Tunnel device i/f down handler
*/
-void nss_tun6rd_dev_down(struct net_device *netdev)
+static int nss_tun6rd_dev_down(struct net_device *netdev)
{
struct ip_tunnel *tunnel;
struct ip_tunnel_6rd_parm *ip6rd;
- struct nss_tun6rd_msg tun6rdmsg;
- struct nss_tun6rd_destroy_msg *tun6rdcfg;
+ int32_t if_number;
nss_tx_status_t status;
/*
- * Check if tunnel 6rd is registered ?
- */
- if (g_tun6rd.nss_ctx == NULL) {
- return;
- }
-
- /*
* Validate netdev for ipv6-in-ipv4 Tunnel
*/
- if (netdev->type != ARPHRD_SIT ) {
- return;
+ if (netdev->type != ARPHRD_SIT) {
+ return NOTIFY_BAD;
}
- tunnel = (struct ip_tunnel*)netdev_priv(netdev);
+ /*
+ * Check if tunnel 6rd is registered ?
+ */
+ if_number = nss_cmn_get_interface_number_by_dev(netdev);
+ if (if_number < 0) {
+ nss_tun6rd_warning("Net device:%p is not registered \n",netdev);
+ return NOTIFY_BAD;
+ }
+
+
+ tunnel = (struct ip_tunnel *)netdev_priv(netdev);
ip6rd = &tunnel->ip6rd;
/*
@@ -268,53 +330,27 @@
if ((ip6rd->prefixlen == 0 )
|| (ip6rd->relay_prefixlen > 32 )
|| (ip6rd->prefixlen
- + (32 - ip6rd->relay_prefixlen) > 64)){
+ + (32 - ip6rd->relay_prefixlen) > 64)) {
- nss_tun6rd_error("Invalid 6rd argument prefix len %d \
- relayprefix len %d \n",
+ nss_tun6rd_warning("Invalid 6rd argument prefix len %d relayprefix len %d \n",
ip6rd->prefixlen,ip6rd->relay_prefixlen);
- return;
- }
-
- /*
- * Prepare The Tunnel configuration parameter to send to nss
- */
- memset(&tun6rdmsg, 0, sizeof(struct nss_tun6rd_msg));
- tun6rdcfg = &tun6rdmsg.msg.tun6rd_destroy;
-
- tun6rdcfg->prefix[0] = ntohl(ip6rd->prefix.s6_addr32[0]);
- tun6rdcfg->prefix[1] = ntohl(ip6rd->prefix.s6_addr32[1]);
- tun6rdcfg->prefix[2] = ntohl(ip6rd->prefix.s6_addr32[2]);
- tun6rdcfg->prefix[3] = ntohl(ip6rd->prefix.s6_addr32[3]);
-
- nss_tun6rd_trace(" Prefix %x:%x:%x:%x Prefix len %d \n",
- ip6rd->prefix.s6_addr32[0], ip6rd->prefix.s6_addr32[1],
- ip6rd->prefix.s6_addr32[2], ip6rd->prefix.s6_addr32[3],
- ip6rd->prefixlen);
-
- nss_tun6rd_trace("Sending Tunnle 6rd Down command %x \n",g_tun6rd.if_num);
-
- /*
- * Send 6rd Tunnel DESTROY command to NSS
- */
- nss_cmn_msg_init(&tun6rdmsg.cm, NSS_TUN6RD_INTERFACE, NSS_TUN6RD_TX_IF_DESTROY,
- sizeof(struct nss_tun6rd_destroy_msg), NULL, NULL);
-
- status = nss_tun6rd_tx(g_tun6rd.nss_ctx, &tun6rdmsg);
- if (status != NSS_TX_SUCCESS) {
- nss_tun6rd_error("Tunnel down command error %d \n", status);
- return;
+ return NOTIFY_BAD;
}
/*
* Un-Register 6rd tunnel with NSS
*/
- nss_unregister_tun6rd_if(g_tun6rd.if_num);
- g_tun6rd.nss_ctx = NULL;
- g_tun6rd.device_up = 0;
- return;
+ nss_unregister_tun6rd_if(if_number);
+ status = nss_dynamic_interface_dealloc_node(if_number, NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD);
+ if (status != NSS_TX_SUCCESS) {
+ nss_tun6rd_warning("Dealloc node failure\n");
+ return NOTIFY_BAD;
+ }
+
+ return NOTIFY_DONE;
}
+
/*
* nss_tun6rd_dev_event()
* Net device notifier for 6rd module
@@ -324,23 +360,17 @@
{
struct net_device *netdev = (struct net_device *)dev;
- nss_tun6rd_trace("%s\n",__FUNCTION__);
switch (event) {
case NETDEV_UP:
- nss_tun6rd_trace(" NETDEV_UP :event %lu name %s \n",
- event,netdev->name);
- nss_tun6rd_dev_up(netdev);
- break;
+ nss_tun6rd_trace("NETDEV_UP: event %lu name %s\n", event, netdev->name);
+ return nss_tun6rd_dev_up(netdev);
case NETDEV_DOWN:
- nss_tun6rd_trace(" NETDEV_DOWN :event %lu name %s \n",
- event,netdev->name);
- nss_tun6rd_dev_down(netdev);
- break;
+ nss_tun6rd_trace("NETDEV_DOWN: event %lu name %s\n", event, netdev->name);
+ return nss_tun6rd_dev_down(netdev);
default:
- nss_tun6rd_trace("Unhandled notifier dev %s event %x \n",
- netdev->name,(int)event);
+ nss_tun6rd_trace("Unhandled notifier event %lu name %s\n",event, netdev->name);
break;
}
@@ -348,87 +378,12 @@
}
/*
- * nss_tun6rd_exception()
- * Exception handler registered to NSS driver
+ * Linux Net device Notifier
*/
-void nss_tun6rd_exception(void *ctx, void *buf, __attribute__((unused)) struct napi_struct *napi)
-{
- struct net_device *dev = (struct net_device *)ctx;
- struct sk_buff *skb = (struct sk_buff *)buf;
- const struct iphdr *iph;
+struct notifier_block nss_tun6rd_notifier = {
+ .notifier_call = nss_tun6rd_dev_event,
+};
- skb->dev = dev;
- nss_tun6rd_info("received - %d bytes name %s ver %x \n",
- skb->len,dev->name,skb->data[0]);
-
- iph = (const struct iphdr *)skb->data;
-
- /*
- * Packet after Decap/Encap Did not find the Rule.
- */
- if (iph->version == 4) {
- if(iph->protocol == IPPROTO_IPV6){
- skb_pull(skb, sizeof(struct iphdr));
- skb->protocol = htons(ETH_P_IPV6);
- skb_reset_network_header(skb);
- skb->pkt_type = PACKET_HOST;
- skb->ip_summed = CHECKSUM_NONE;
- dev_queue_xmit(skb);
- return;
- }
- skb->protocol = htons(ETH_P_IP);
- } else {
- skb->protocol = htons(ETH_P_IPV6);
- }
-
- skb_reset_network_header(skb);
- skb->pkt_type = PACKET_HOST;
- skb->skb_iif = dev->ifindex;
- skb->ip_summed = CHECKSUM_NONE;
- netif_receive_skb(skb);
-}
-
-/*
- * nss_tun6rd_update_dev_stats
- * Update the Dev stats received from NetAp
- */
-static void nss_tun6rd_update_dev_stats(struct net_device *dev,
- struct nss_tun6rd_stats_sync_msg *sync_stats)
-{
- struct nss_tun6rd_stats stats;
- void *ptr;
-
- stats.rx_packets = sync_stats->node_stats.rx_packets;
- stats.rx_bytes = sync_stats->node_stats.rx_bytes;
- stats.tx_packets = sync_stats->node_stats.tx_packets;
- stats.tx_bytes = sync_stats->node_stats.tx_bytes;
-
- ptr = (void *)&stats;
- ipip6_update_offload_stats(dev, ptr);
-}
-
-/**
- * @brief Event Callback to receive events from NSS
- * @param[in] pointer to net device context
- * @param[in] pointer to buffer
- * @return Returns void
- */
-void nss_tun6rd_event_receive(void *if_ctx, struct nss_tun6rd_msg *tnlmsg)
-{
- struct net_device *netdev = NULL;
- netdev = (struct net_device *)if_ctx;
-
- switch (tnlmsg->cm.type) {
- case NSS_TUN6RD_RX_STATS_SYNC:
- nss_tun6rd_update_dev_stats(netdev, (struct nss_tun6rd_stats_sync_msg *)&tnlmsg->msg.stats_sync);
- break;
-
- default:
- nss_tun6rd_info("%s: Unknown Event from NSS",
- __FUNCTION__);
- break;
- }
-}
/*
* nss_tun6rd_init_module()
@@ -442,11 +397,6 @@
register_netdevice_notifier(&nss_tun6rd_notifier);
nss_tun6rd_trace("Netdev Notifier registerd \n");
- g_tun6rd.if_num = NSS_TUN6RD_INTERFACE;
- g_tun6rd.netdev = NULL;
- g_tun6rd.device_up = 0;
- g_tun6rd.nss_ctx = NULL;
-
return 0;
}
@@ -456,7 +406,6 @@
*/
void __exit nss_tun6rd_exit_module(void)
{
-
unregister_netdevice_notifier(&nss_tun6rd_notifier);
nss_tun6rd_info("module unloaded\n");
}
diff --git a/nss_dynamic_interface.c b/nss_dynamic_interface.c
index 6b35852..ced3dea 100644
--- a/nss_dynamic_interface.c
+++ b/nss_dynamic_interface.c
@@ -336,5 +336,15 @@
di.current_if_num = -1;
}
+/*
+ * nss_is_dynamic_interface()
+ * Judge it is a valid dynamic interface
+ */
+bool nss_is_dynamic_interface(int if_num)
+{
+ return (if_num >= NSS_DYNAMIC_IF_START && if_num < NSS_SPECIAL_IF_START);
+}
+
EXPORT_SYMBOL(nss_dynamic_interface_alloc_node);
EXPORT_SYMBOL(nss_dynamic_interface_dealloc_node);
+EXPORT_SYMBOL(nss_is_dynamic_interface);
diff --git a/nss_init.c b/nss_init.c
index 646ab0d..1a6e56b 100755
--- a/nss_init.c
+++ b/nss_init.c
@@ -370,7 +370,6 @@
if (npd->tun6rd_enabled == NSS_FEATURE_ENABLED) {
nss_top->tun6rd_handler_id = nss_dev->id;
- nss_tun6rd_register_handler();
}
if (npd->tunipip6_enabled == NSS_FEATURE_ENABLED) {
diff --git a/nss_tun6rd.c b/nss_tun6rd.c
index b4d83d0..705f041 100644
--- a/nss_tun6rd.c
+++ b/nss_tun6rd.c
@@ -24,9 +24,11 @@
{
struct nss_tun6rd_msg *ntm = (struct nss_tun6rd_msg *)ncm;
void *ctx;
+
nss_tun6rd_msg_callback_t cb;
- BUG_ON(ncm->interface != NSS_TUN6RD_INTERFACE);
+ BUG_ON(!nss_is_dynamic_interface(ncm->interface));
+
/*
* Is this a valid request/response packet?
*/
@@ -77,7 +79,6 @@
cb(ctx, ntm);
}
-
/*
* nss_tun6rd_tx()
* Transmit a tun6rd message to NSSFW
@@ -98,7 +99,7 @@
/*
* Sanity check the message
*/
- if (ncm->interface != NSS_TUN6RD_INTERFACE) {
+ if (!nss_is_dynamic_interface(ncm->interface)) {
nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
return NSS_TX_FAILURE;
}
@@ -151,17 +152,26 @@
/*
* nss_register_tun6rd_if()
*/
-struct nss_ctx_instance *nss_register_tun6rd_if(uint32_t if_num,
- nss_tun6rd_callback_t tun6rd_callback,
- nss_tun6rd_msg_callback_t event_callback, struct net_device *netdev)
+struct nss_ctx_instance *nss_register_tun6rd_if(uint32_t if_num, nss_tun6rd_callback_t tun6rd_callback,
+ nss_tun6rd_msg_callback_t event_callback, struct net_device *netdev)
{
- nss_assert((if_num >= NSS_MAX_VIRTUAL_INTERFACES) && (if_num < NSS_MAX_NET_INTERFACES));
+ nss_assert((if_num >= NSS_DYNAMIC_IF_START) && (if_num < NSS_SPECIAL_IF_START));
- nss_top_main.if_ctx[if_num] = netdev;
- nss_top_main.if_rx_callback[if_num] = tun6rd_callback;
- nss_top_main.tun6rd_msg_callback = event_callback;
+ nss_top_main.if_ctx[if_num] = netdev;
+ nss_top_main.if_rx_callback[if_num] = tun6rd_callback;
+ nss_top_main.tun6rd_msg_callback = event_callback;
- return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tun6rd_handler_id];
+ nss_core_register_handler(if_num, nss_tun6rd_handler, NULL);
+
+ return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tun6rd_handler_id];
+}
+
+/*
+ * nss_get_tun6rd_context()
+ */
+struct nss_ctx_instance * nss_tun6rd_get_context()
+{
+ return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tun6rd_handler_id];
}
/*
@@ -169,22 +179,16 @@
*/
void nss_unregister_tun6rd_if(uint32_t if_num)
{
- nss_assert((if_num >= NSS_MAX_VIRTUAL_INTERFACES) && (if_num < NSS_MAX_NET_INTERFACES));
+ nss_assert(nss_is_dynamic_interface(ncm->interface));
- nss_top_main.if_rx_callback[if_num] = NULL;
- nss_top_main.if_ctx[if_num] = NULL;
- nss_top_main.tun6rd_msg_callback = NULL;
+ nss_top_main.if_rx_callback[if_num] = NULL;
+ nss_top_main.if_ctx[if_num] = NULL;
+ nss_top_main.tun6rd_msg_callback = NULL;
+
+ nss_core_unregister_handler(if_num);
}
-/*
- * nss_tun6rd_register_handler()
- */
-void nss_tun6rd_register_handler()
-{
- nss_core_register_handler(NSS_TUN6RD_INTERFACE, nss_tun6rd_handler, NULL);
-}
-
-
+EXPORT_SYMBOL(nss_tun6rd_get_context);
EXPORT_SYMBOL(nss_tun6rd_tx);
EXPORT_SYMBOL(nss_register_tun6rd_if);
EXPORT_SYMBOL(nss_unregister_tun6rd_if);
diff --git a/nss_tx_rx_common.h b/nss_tx_rx_common.h
index 9d155bd..9e29a30 100644
--- a/nss_tx_rx_common.h
+++ b/nss_tx_rx_common.h
@@ -69,7 +69,6 @@
extern void nss_ipv4_register_handler(void);
extern void nss_ipv6_register_handler(void);
extern void nss_n2h_register_handler(void);
-extern void nss_tun6rd_register_handler(void);
extern void nss_tunipip6_register_handler(void);
extern void nss_pppoe_register_handler(void);
extern void nss_core_freq_register_handler(void);