blob: a186690f85f939d71aa1e613a70e7ffbd6b6400c [file] [log] [blame]
/*
* Copyright (c) 2012, 2015, 2018, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef KVER32
#include <linux/kconfig.h>
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/netfilter_arp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <net/netfilter/nf_conntrack.h>
#include "fal_nat.h"
#include "fal_ip.h"
#include "hsl_api.h"
#include "hsl.h"
#include "hsl_shared_api.h"
#include "../nat_helper.h"
#include "nat_helper_dt.h"
#include "nat_helper_hsl.h"
#include "../napt_acl.h"
int nat_chip_ver = 0;
a_bool_t napt_add_bypass_check = A_TRUE;
/* support 4 different interfaces (or 4 VLANs) */
static fal_intf_mac_entry_t global_if_mac_entry[MAX_INTF_NUM] = {{0}};
static a_uint8_t if_mac_count = 0;
extern int setup_wan_if;
extern int setup_lan_if;
#define DESS_CHIP(ver) ((((ver)&0xffff)>>8) == NAT_CHIP_VER_DESS)
#define ARP_HW_COUNTER_OFFSET 8
static a_uint8_t
nat_hw_debug_counter_get(void)
{
static a_uint32_t nat_debug_counter = 0;
return ((nat_debug_counter++) & 0x7);
}
static a_uint8_t
arp_hw_debug_counter_get(void)
{
static a_uint32_t ip_debug_counter = 0;
return ((ip_debug_counter++) & 0x7) + ARP_HW_COUNTER_OFFSET;
}
a_int32_t
nat_hw_add(nat_entry_t *nat)
{
fal_nat_entry_t hw_nat = {0};
hw_nat.flags = nat->flags;
hw_nat.src_addr = nat->src_addr;
hw_nat.trans_addr = nat->trans_addr;
hw_nat.port_num = nat->port_num;
hw_nat.port_range = nat->port_range;
hw_nat.counter_en = 1;
hw_nat.counter_id = nat_hw_debug_counter_get();
if(NAT_ADD(0, &hw_nat) != 0)
{
return -1;
}
nat->entry_id = hw_nat.entry_id;
return 0;
}
a_int32_t
nat_hw_del_by_index(a_uint32_t index)
{
fal_nat_entry_t nat_entry = {0};
HNAT_PRINTK("NAT_DEL(1) index=%d########\n", index);
nat_entry.entry_id = index;
if(NAT_DEL(0, FAL_NAT_ENTRY_ID_EN, &nat_entry)!= 0)
{
return -1;
}
return 0;
}
a_int32_t
nat_hw_flush(void)
{
if(NAT_DEL(0, 0, 0)!= 0)
{
return -1;
}
return 0;
}
a_int32_t
napt_hw_flush(void)
{
if(NAPT_DEL(0, 0, 0)!= 0)
{
return -1;
}
return 0;
}
static a_uint32_t private_ip_can_update = 1;
a_int32_t
nat_hw_prv_base_can_update(void)
{
return private_ip_can_update;
}
void
nat_hw_prv_base_update_enable(void)
{
private_ip_can_update = 1;
}
void
nat_hw_prv_base_update_disable(void)
{
private_ip_can_update = 0;
}
static a_uint32_t private_ip_base = 0xc0a80000;
static a_uint32_t private_net_mask = 0xffffff00;
a_int32_t
nat_hw_prv_base_set(a_uint32_t ip)
{
#define PRIVATE_IP_MASK 0xffffff00
ip = ntohl(ip);
if (((nat_chip_ver & 0xffff) >> 8) == NAT_CHIP_VER_8327)
private_ip_base = ip & PRIVATE_IP_MASK;
else
private_ip_base = ip & nat_hw_prv_mask_get();
if(DESS_CHIP(nat_chip_ver)) {
if (IP_PRV_BASE_ADDR_SET(0, 0, (fal_ip4_addr_t)ip) != 0)
{
return -1;
}
} else {
if (NAT_PRV_BASE_ADDR_SET(0, (fal_ip4_addr_t)ip) != 0)
{
return -1;
}
}
HNAT_PRINTK("%s: private_ip_base:%x private_ip_can_update:%d\n",
__func__, private_ip_base, private_ip_can_update);
return 0;
}
a_uint32_t
nat_hw_prv_base_get(void)
{
return private_ip_base;
}
a_int32_t
nat_hw_prv_mask_set(a_uint32_t ipmask)
{
ipmask = ntohl(ipmask);
if(DESS_CHIP(nat_chip_ver)) {
if (IP_PRV_BASE_MASK_SET(0, 0, (fal_ip4_addr_t)ipmask) != 0)
{
return -1;
}
} else if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8337) {
if (NAT_PRV_BASE_MASK_SET(0, (fal_ip4_addr_t)ipmask) != 0)
{
return -1;
}
}
private_net_mask = ipmask;
HNAT_PRINTK("%s: 0x%08x\n", __FUNCTION__, private_net_mask);
return 0;
}
a_uint32_t
nat_hw_prv_mask_get(void)
{
return private_net_mask;
}
a_int32_t
nat_hw_prv_base_is_match(a_uint32_t ip)
{
#define PRIVATE_IP_MASK 0xffffff00
a_uint32_t prv_base = private_ip_base;
a_uint32_t prv_mask;
if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) {
if((prv_base & PRIVATE_IP_MASK) == (ip & PRIVATE_IP_MASK))
return 1;
} else {
prv_mask = nat_hw_prv_mask_get();
if((prv_base & prv_mask) == (ip & prv_mask))
return 1;
}
HNAT_PRINTK("%s: private_ip_base:%x usaddr:%x mismatch\n",
__func__, prv_base, ip);
return 0;
}
static a_int32_t
_arp_hw_if_mac_add(fal_intf_mac_entry_t *if_mac_entry)
{
return IP_INTF_ENTRY_ADD(0, if_mac_entry);
}
static a_int32_t
_arp_hw_if_mac_del(fal_intf_mac_entry_t *if_mac_entry)
{
return IP_INTF_ENTRY_DEL(0, FAL_IP_ENTRY_ID_EN, if_mac_entry);
}
a_int32_t
if_mac_cleanup(void)
{
a_uint8_t i = 0;
if_mac_count = 0;
for(i = 0; i < MAX_INTF_NUM; i++)
{
if(_arp_hw_if_mac_del(&global_if_mac_entry[i]) != 0) {
printk("mac del fail!\n");
return -1;
}
memset(&global_if_mac_entry[i], 0, sizeof(fal_intf_mac_entry_t));
}
setup_wan_if = 0;
setup_lan_if = 0;
return 0;
}
#define MACADDR_LEN 6
a_int32_t
if_mac_add(a_uint8_t *mac, a_uint32_t vid, uint32_t ipv6)
{
a_uint8_t i = 0;
a_uint8_t zero_mac[MACADDR_LEN] = {0};
if (!memcmp(mac, zero_mac, MACADDR_LEN))
return 0;
if(if_mac_count > MAX_INTF_NUM)
return -1;
for(i = 0; i < if_mac_count; i++)
{
if((!memcmp(global_if_mac_entry[i].mac_addr.uc, mac, 6)) &&
(global_if_mac_entry[i].vid_low == vid))
{
HNAT_PRINTK("%s: mac exist id:%d\n", __func__,
global_if_mac_entry[i].entry_id);
return 0;
}
}
if(if_mac_count == MAX_INTF_NUM)
{
HNAT_ERR_PRINTK("%s: reach mac count max\n", __func__);
return -1;
}
memset(&global_if_mac_entry[if_mac_count], 0, sizeof(fal_intf_mac_entry_t));
memcpy(global_if_mac_entry[if_mac_count].mac_addr.uc, mac, 6);
global_if_mac_entry[if_mac_count].entry_id = if_mac_count;
if (1 == ipv6)
{
global_if_mac_entry[if_mac_count].ip6_route = 1;
}
else
{
global_if_mac_entry[if_mac_count].ip6_route = 0;
}
global_if_mac_entry[if_mac_count].ip4_route = 1;
if (vid == 0)
{
global_if_mac_entry[if_mac_count].vid_low = 0;
global_if_mac_entry[if_mac_count].vid_high = 511;
}
else
{
global_if_mac_entry[if_mac_count].vid_low = vid;
global_if_mac_entry[if_mac_count].vid_high = vid;
}
if(_arp_hw_if_mac_add(&global_if_mac_entry[if_mac_count])!= 0)
{
return -1;
}
HNAT_PRINTK("%s: count:%d index:%d vid:%d mac:%02x-%02x-%02x-%02x-%02x-%02x\n",
__func__, if_mac_count, global_if_mac_entry[if_mac_count].entry_id, vid,
mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
if_mac_count ++;
return 0;
}
static a_int32_t
_arp_hw_add(fal_host_entry_t *arp_entry)
{
return IP_HOST_ADD(0, arp_entry);
}
a_int32_t
arp_hw_add(a_uint32_t port, a_uint32_t intf_id, a_uint8_t *ip, a_uint8_t *mac, int is_ipv6_entry)
{
fal_host_entry_t arp_entry;
#ifdef ISIS /* Only for AR8337(S17) */
if (NF_S17_WAN_TYPE_PPPOEV6 == nf_athrs17_hnat_wan_type)
{
memset(&arp_entry,0,sizeof(arp_entry));
memcpy(&arp_entry.ip4_addr, ip, 4);
memcpy(arp_entry.mac_addr.uc, mac, 6);
arp_entry.status = ARP_AGE_NEVER;
if (port == S17_WAN_PORT)
{
arp_entry.port_id = port;
}
else
{
arp_entry.port_id = 6; /* always assigned to MAC 6 */
}
arp_entry.flags = FAL_IP_IP4_ADDR;
}
else
#endif /* not ISIS */
{
memset(&arp_entry,0,sizeof(arp_entry));
if (0 == is_ipv6_entry)
{
memcpy(&arp_entry.ip4_addr, ip, 4);
arp_entry.ip4_addr = ntohl(arp_entry.ip4_addr);
arp_entry.flags = FAL_IP_IP4_ADDR;
}
else
{
memcpy(&arp_entry.ip6_addr, ip, 16);
arp_entry.flags = FAL_IP_IP6_ADDR;
}
memcpy(arp_entry.mac_addr.uc, mac, 6);
if ((NF_S17_WAN_TYPE_PPPOE == nf_athrs17_hnat_wan_type) && \
(S17_WAN_PORT == port))
{
arp_entry.status = ARP_AGE_NEVER;
}
else
{
arp_entry.status = ARP_AGE;
}
arp_entry.port_id = port;
}
arp_entry.intf_id = intf_id;
arp_entry.counter_en = 1;
if (S17_WAN_PORT == port)
{
arp_entry.counter_id = 0xf;
}
else
{
arp_entry.counter_id = arp_hw_debug_counter_get();
}
if (IP_HOST_GET(0, 0x10, &arp_entry)) {
HNAT_PRINTK("new arp for 0x%x\n", arp_entry.ip4_addr);
if(_arp_hw_add(&arp_entry) != 0)
{
HNAT_ERR_PRINTK("%s: fail\n", __func__);
return -1;
}
}
if (0 == is_ipv6_entry)
{
HNAT_PRINTK("%s: index:%x port:%d ip:%d.%d.%d.%d\n",
__func__, arp_entry.entry_id, port,
*(ip), *(ip+1), *(ip+2), *(ip+3));
}
if (0 != (arp_entry.entry_id & 0xFFFFFC00))
{
printk("Warning: arp_entry id should be only 10 bits!\n");
}
return arp_entry.entry_id;
}
#define AOS_HEADER_MAGIC 0xC0DE
a_int32_t
arp_if_info_get(void *data, a_uint32_t *sport, a_uint32_t *vid)
{
aos_header_t *athr_header = NULL;
if((data==0) || (sport==0) || (vid==0))
{
return -1;
}
athr_header = (aos_header_t *)data;
#if 0
/*atheros header magic check*/
if(athr_header->magic != AOS_HEADER_MAGIC)
{
return -1;
}
#endif
*sport = athr_header->sport;
*vid = athr_header->vid;
return 0;
}
#define MAX_PUBLIC_IP_CNT 16
struct public_ip_shadow
{
a_uint32_t ip;
a_uint32_t use_cnt;
};
static struct public_ip_shadow public_ip_shadow[MAX_PUBLIC_IP_CNT]= {{0}};
static a_uint32_t public_ip_cnt = 0;
a_int32_t
nat_hw_pub_ip_add(a_uint32_t ip, a_uint32_t *index)
{
sw_error_t rv;
a_uint32_t hw_index;
a_uint32_t i;
fal_nat_pub_addr_t ip_entry;
for(i=0; i<MAX_PUBLIC_IP_CNT; i++)
{
if((ip == public_ip_shadow[i].ip) && (public_ip_shadow[i].use_cnt))
{
public_ip_shadow[i].use_cnt++;
*index = i;
return 0;
}
}
if(public_ip_cnt >= MAX_PUBLIC_IP_CNT)
{
return -1;
}
memset(&ip_entry, 0, sizeof(ip_entry));
ip_entry.pub_addr = ip;
rv = NAT_PUB_ADDR_ADD(0,&ip_entry);
if(rv != 0)
{
return -1;
}
public_ip_cnt++;
hw_index = ip_entry.entry_id;
public_ip_shadow[hw_index].ip = ip;
public_ip_shadow[hw_index].use_cnt++;
*index = hw_index;
HNAT_PRINTK("%s: public_ip_cnt:%d index:%d ip:0x%x\n",
__func__, public_ip_cnt, hw_index, public_ip_shadow[hw_index].ip);
return 0;
}
void
napt_hw_mode_init(void)
{
sw_error_t rv;
/* age_speedup+age_thres_1/4+age_step_4+age_timer_28s*1+
stop_age_when1+overwrite_disable */
/* Also set NAT mode Port strict mode/symmetric mode */
a_uint32_t entry = 0x15F01CB;
REG_ENTRY_SET(rv, 0, NAT_CTRL, 0, (a_uint8_t *) (&entry),
sizeof (a_uint32_t));
REG_ENTRY_GET(rv, 0, ROUTER_CTRL, 0,
(a_uint8_t *) (&entry), sizeof (a_uint32_t));
/*set locktime 100us*/
SW_SET_REG_BY_FIELD(ROUTER_CTRL, GLB_LOCKTIME, 1, entry);
SW_SET_REG_BY_FIELD(ROUTER_CTRL, ARP_AGE_MODE, 1, entry);
REG_ENTRY_SET(rv, 0, ROUTER_CTRL, 0,
(a_uint8_t *) (&entry), sizeof (a_uint32_t));
REG_ENTRY_GET(rv, 0, MOD_ENABLE, 0,
(a_uint8_t *) (&entry), sizeof (a_uint32_t));
SW_SET_REG_BY_FIELD(MOD_ENABLE, L3_EN, 1, entry);
REG_ENTRY_SET(rv, 0, MOD_ENABLE, 0,
(a_uint8_t *) (&entry), sizeof (a_uint32_t));
ACL_STATUS_SET(0, A_TRUE);
}
void
napt_hw_mode_cleanup(void)
{
a_uint32_t entry;
sw_error_t rv;
if (!DESS_CHIP(nat_chip_ver)) {
IP_ROUTE_STATUS_SET(0, A_FALSE);
entry = 0;
} else {
REG_ENTRY_GET(rv, 0, NAT_CTRL, 0,
(a_uint8_t *) (&entry), sizeof (a_uint32_t));
SW_SET_REG_BY_FIELD(NAT_CTRL, NAT_EN, 0, entry);
}
REG_ENTRY_SET(rv, 0, NAT_CTRL, 0,
(a_uint8_t *) (&entry), sizeof (a_uint32_t));
ACL_STATUS_SET(0, A_FALSE);
}
a_int32_t
nat_hw_pub_ip_del(a_uint32_t index)
{
sw_error_t rv;
if(public_ip_shadow[index].use_cnt>0)
{
public_ip_shadow[index].use_cnt--;
if(public_ip_shadow[index].use_cnt == 0)
{
fal_nat_pub_addr_t ip_entry;
HNAT_PRINTK("%s: public_ip_cnt:%d index:%d ip:0x%x\n",
__func__, public_ip_cnt, index, public_ip_shadow[index].ip);
memset(&ip_entry,0,sizeof(ip_entry));
ip_entry.pub_addr = public_ip_shadow[index].ip;
rv = NAT_PUB_ADDR_DEL(0, 1, &ip_entry);
if(rv != 0)
{
return -1;
}
public_ip_cnt--;
}
return 0;
}
return -1;
}
#define napt_entry_cp(to, from) \
{ \
(to)->entry_id = (from)->entry_id; \
(to)->status = (from)->status; \
(to)->flags = (from)->flags; \
(to)->src_addr = (from)->src_addr; \
(to)->src_port = (from)->src_port; \
(to)->dst_addr = (from)->dst_addr; \
(to)->dst_port = (from)->dst_port; \
(to)->trans_addr = (from)->trans_addr; \
(to)->trans_port = (from)->trans_port; \
(to)->ingress_packet = (from)->ingress_packet; \
(to)->ingress_byte = (from)->ingress_byte; \
(to)->egress_packet = (from)->egress_packet; \
(to)->egress_byte = (from)->egress_byte; \
}
a_int32_t
napt_hw_add(napt_entry_t *napt)
{
a_int32_t ret = 0;
fal_napt_entry_t fal_napt = {0};
fal_host_entry_t host_entry = {0};
a_uint32_t next_hop = 0;
napt_entry_cp(&fal_napt, napt);
fal_napt.flags |= FAL_NAT_ENTRY_TRANS_IPADDR_INDEX;
fal_napt.counter_en = 1;
fal_napt.counter_id = nat_hw_debug_counter_get();
fal_napt.action = FAL_MAC_FRWRD;
if (!napt_add_bypass_check) {
/*check arp entry*/
host_entry.flags = FAL_IP_IP4_ADDR;
host_entry.ip4_addr = fal_napt.src_addr;
ret = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &host_entry);
if (ret) {
HNAT_ERR_PRINTK("can not find src host entry!\n");
return ret;
}
if (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOE) {
next_hop = get_next_hop(fal_napt.dst_addr, fal_napt.src_addr);
host_entry.ip4_addr = next_hop ? next_hop : fal_napt.dst_addr;
ret = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &host_entry);
if (ret) {
HNAT_ERR_PRINTK("can not find dst host entry!\n");
return ret;
}
}
}
ret = NAPT_ADD(0, &fal_napt);
napt->entry_id = fal_napt.entry_id;
return ret;
}
a_int32_t
napt_hw_get(napt_entry_t *napt, fal_napt_entry_t *entry)
{
a_int32_t ret = 0;
fal_napt_entry_t fal_napt = {0};
napt_entry_cp(&fal_napt, napt);
ret = NAPT_GET(0, 0, &fal_napt);
if(!ret)
*entry = fal_napt;
return ret;
}
a_int32_t
napt_hw_dnat_cookie_add(napt_entry_t *napt, a_uint32_t cookie)
{
a_int32_t ret = 0;
fal_napt_entry_t fal_napt = {0};
fal_napt.flags = napt->flags | 0x10;
fal_napt.status = 0xf;
fal_napt.dst_addr = napt->dst_addr;
fal_napt.dst_port = napt->dst_port;
fal_napt.trans_addr = napt->trans_addr;
fal_napt.trans_port = napt->trans_port;
fal_napt.src_port = napt->src_port;
fal_napt.action = FAL_MAC_RDT_TO_CPU;
fal_napt.flow_cookie = cookie;
ret = NAPT_ADD(0, &fal_napt);
return ret;
}
a_int32_t
napt_hw_snat_cookie_add(napt_entry_t *napt, a_uint32_t cookie)
{
a_int32_t ret = 0;
fal_napt_entry_t fal_napt = {0};
fal_napt.flags = napt->flags | 0x10;
fal_napt.status = 0xf;
fal_napt.dst_addr = napt->dst_addr;
fal_napt.dst_port = napt->dst_port;
fal_napt.src_addr = napt->src_addr;
fal_napt.src_port = napt->src_port;
fal_napt.trans_port = napt->trans_port;
fal_napt.action = FAL_MAC_RDT_TO_CPU;
fal_napt.flow_cookie = cookie;
ret = NAPT_ADD(0, &fal_napt);
return ret;
}
a_int32_t
napt_hw_del(napt_entry_t *napt)
{
a_int32_t ret = 0;
fal_napt_entry_t fal_napt = {0};
napt_entry_cp(&fal_napt, napt);
napt_ct_counter_decrease();
ret = NAPT_DEL(0, FAL_NAT_ENTRY_KEY_EN, &fal_napt);
if(ret != 0)
{
return -1;
}
else
{
return 0;
}
}
a_int32_t
napt_hw_first_by_age(napt_entry_t *napt, a_uint32_t age)
{
a_int32_t ret = 0;
fal_napt_entry_t fal_napt = {0};
fal_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
fal_napt.status = age;
if(NAPT_NEXT(0, FAL_NAT_ENTRY_AGE_EN ,&fal_napt) !=0)
{
ret = -1;
}
napt_entry_cp(napt, &fal_napt);
return ret;
}
a_int32_t
napt_hw_next_by_age(napt_entry_t *napt, a_uint32_t age)
{
a_int32_t ret = 0;
fal_napt_entry_t fal_napt = {0};
fal_napt.entry_id = napt->entry_id;
fal_napt.status = age;
if(NAPT_NEXT(0, FAL_NAT_ENTRY_AGE_EN ,&fal_napt) !=0)
{
ret = -1;
}
napt_entry_cp(napt, &fal_napt);
return ret;
}
a_int32_t
napt_hw_get_by_index(napt_entry_t *napt, a_uint16_t hw_index)
{
fal_napt_entry_t fal_napt = {0};
sw_error_t rv;
if(hw_index == 0)
{
fal_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
}
else
{
fal_napt.entry_id = hw_index - 1;
}
if((rv = NAPT_NEXT(0, 0, &fal_napt)) != 0)
{
HNAT_ERR_PRINTK("<napt_hw_get_by_index>[rv:%d] error hw:%x sw:%x\n",
rv, napt->entry_id, hw_index);
return -1;
}
napt_entry_cp(napt, &fal_napt);
if(napt->entry_id != hw_index)
{
HNAT_ERR_PRINTK("<napt_hw_get_by_index>hw_index error hw:%x sw:%x\n",
napt->entry_id, hw_index);
return -1;
}
return 0;
}
a_int32_t napt_hw_get_by_sip(a_uint32_t sip)
{
fal_napt_entry_t napt;
memset(&napt, 0, sizeof(fal_napt_entry_t));
napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
napt.src_addr = sip;
if (NAPT_NEXT(0, FAL_NAT_ENTRY_SOURCE_IP_EN, &napt) == SW_OK) {
return 0;
}
return -1;
}
a_uint32_t
napt_hw_used_count_get(void)
{
#define NAPT_USED_COUNT
#define NAPT_USED_COUNT_OFFSET 0x0e44 /*was:0x0e38*/
#define NAPT_USED_COUNT_E_LENGTH 11
#define NAPT_USED_COUNT_E_OFFSET 0x0
#define NAPT_USED_COUNT_NR_E 1
sw_error_t rv;
a_uint32_t count = 0;
REG_ENTRY_GET(rv, 0, NAPT_USED_COUNT, 0, (a_uint8_t *) (&count),
sizeof (a_uint32_t));
return count;
}
sw_error_t napt_l3_status_set(a_uint32_t dev_id, a_bool_t enable)
{
sw_error_t rv;
a_uint32_t val;
if (A_TRUE == enable)
{
val = 1;
}
else if (A_FALSE == enable)
{
val = 0;
}
else
{
return SW_BAD_PARAM;
}
HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, L3_EN, (a_uint8_t *) (&val),
sizeof (a_uint32_t));
return rv;
}
sw_error_t napt_l3_status_get(a_uint32_t dev_id, a_bool_t * enable)
{
sw_error_t rv;
a_uint32_t val;
HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN, (a_uint8_t *) (&val),
sizeof (a_uint32_t));
SW_RTN_ON_ERROR(rv);
if (val)
{
*enable = A_TRUE;
}
else
{
*enable = A_FALSE;
}
return SW_OK;
}
sw_error_t napt_helper_hsl_init()
{
return SW_OK;
}