/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_rtnetlink_nae.c,v $ $Revision: 1.2.16.2 $ * $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_rtnetlink_nae.c,v $ * $Author: svc-cmnet $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation Jonas Rendel ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** * Contains netlink handlers for managing Ipv4 and Ipv6 routes as well as * MPLS shortcut routes. */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #ifndef IPCOM_KERNEL #define IPCOM_KERNEL #endif #include "ipnet_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #ifdef IPCOM_FORWARDER_NAE #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include "ipnet_h.h" #include "ipnet_ctrl.h" #include "ipnet_route.h" #include "ipnet_netlink_h.h" #include "ipnet_rtnetlink_h.h" #include "ipcom_sock.h" #include "ipcom_forwarder.h" #include "ipnet_loopback.h" #ifdef IP_PORT_LKM #include "ipcom_lkm.h" /* Needed for Linux PPP interface config */ #endif /* IP_PORT_LKM */ #include "ipnet_eth.h" #ifdef IPCOM_USE_FORWARDER_IPSEC #include #endif /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IP_IN4_IS_ADDR_MULTICAST(x) (((x) & ip_htonl(0xf0000000)) == ip_ntohl (0xe0000000)) /* **************************************************************************** * 5 TYPES **************************************************************************** */ typedef struct Ipnet_rtnetlink_fwc_family { struct { Ip_ptrdiff_t *hash; Ip_ptrdiff_t *done; int aborted; int cont; } state; /* Requested */ struct Ip_nlmsghdr *nlmsg; Ip_u8 family; /* Buffering */ Ipnet_netlink_mem_t *mem; } Ipnet_rtnetlink_fwc_family_t; typedef struct Ipnet_rtnetlink_sac_family { struct { Ip_ptrdiff_t *hash; Ip_ptrdiff_t *done; int aborted; int cont; } state; /* Requested */ struct Ip_nlmsghdr *nlmsg; Ip_u8 family; /* Buffering */ Ipnet_netlink_mem_t *mem; } Ipnet_rtnetlink_sac_family_t; /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ IP_STATIC int ipnet_rtnetlink_fwcache_entry(Ipnet_rtnetlink_fwc_family_t *param, Ip_u32 hash_entry, int domain, Ip_u32 vlan, void *dst, Ip_size_t dst_size, Ip_u8 *mac, Ip_u32 unused) { struct Ip_nlmsghdr *nlh; struct Ip_fwcmsg *fwc; nlh = ipnet_netlink_nlmsg_sz_begin(param->mem, param->nlmsg->nlmsg_seq, IP_RTM_NEWFWCACHE, IP_NLM_F_MULTI); if (!nlh) return -1; fwc = ipnet_netlink_sz_put(param->mem, IP_NULL, sizeof (*fwc)); if (!fwc) return -1; /* * Add route message header */ fwc->fwc_family = domain; fwc->fwc_entry = hash_entry; fwc->fwc_core = ipcom_nae_current_core(); fwc->fwc_nae = ipcom_nae_id(); fwc->fwc_port = mac[0]; fwc->fwc_index = ipcom_nae.nae_port[fwc->fwc_port].netif->ifindex; /* * Add IPSec info */ if ((mac[1] & 0x0f) == IPCOM_FWD_IPSEC_ENCRYPT) fwc->sac_encrypt = 1; else fwc->sac_encrypt = 0; if ((mac[1] & 0x0f) == IPCOM_FWD_IPSEC_DECRYPT) fwc->sac_decrypt = 1; else fwc->sac_decrypt = 0; /* * Put destination address */ if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_DST, dst_size, dst)) return -1; if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_LLADDR, 6, &mac[2])) return -1; if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_UNUSED, sizeof(Ip_u32), &unused)) return -1; if (0 != vlan && !ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_VLAN, sizeof(vlan), &vlan)) return -1; /* * Done */ return ipnet_netlink_nlmsg_sz_end(param->mem, nlh); } #ifdef IPCOM_USE_INET IP_STATIC int ipnet_rtnetlink_fwcache_foreach_inet(Ipnet_rtnetlink_fwc_family_t *param) { unsigned int i = 0; unsigned int f4_limit = ipcom_nae_shm->fw_v4_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS; #ifdef IPCOM_USE_FORWARDER_VLAN unsigned int f6_limit = ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS + f4_limit; #endif if (*param->state.hash < f4_limit) { /* Going through the 'ordinary' v4 */ for (i = *param->state.hash; i < f4_limit; i++) { fw_cache_entry_v4_t *e4 = &ipcom_nae.fw_cache_tbl_v4[i]; if (e4->ip4.rci == ipnet->route_cache_id) { /* Got a player */ if (0 > ipnet_rtnetlink_fwcache_entry(param, i, IP_AF_INET, 0, &e4->ip4.addr, sizeof(e4->ip4.addr), (Ip_u8 *)e4->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(e4) != 0)) goto aborted; } } *param->state.hash = f4_limit; } #ifdef IPCOM_USE_FORWARDER_VLAN if (*param->state.hash < f6_limit) { /* We're going through the VLAN v4 */ for (i = *param->state.hash; i < f6_limit; i++) { fw_cache_entry_vlan_t *ev = (fw_cache_entry_vlan_t *)&ipcom_nae.fw_cache_tbl_v6[i - f4_limit]; if (ev->ipvlan.rci == ipnet->route_cache_id && ev->ipvlan.type == IPCOM_FORWARDER_PACKET_TYPE_IPV4_VLAN) { /* Got a player */ if (0 > ipnet_rtnetlink_fwcache_entry(param, i - f4_limit, IP_AF_INET, ev->ipvlan.vlan_id, &ev->ipvlan.a.addr_v4, sizeof(ev->ipvlan.a.addr_v4), (Ip_u8 *)ev->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(ev) != 0)) goto aborted; } } *param->state.hash = f6_limit; } #endif return 0; aborted: param->state.aborted = 1; *param->state.hash = (Ip_ptrdiff_t)i; return -1; } #endif #ifdef IPCOM_USE_INET6 IP_STATIC int ipnet_rtnetlink_fwcache_foreach_inet6(Ipnet_rtnetlink_fwc_family_t *param) { unsigned int i = 0; unsigned int f6_limit = ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS; if (*param->state.hash < f6_limit) { /* We're going through the VLAN v4 */ for (i = *param->state.hash; i < f6_limit; i++) { fw_cache_entry_v6_t *e6 = &ipcom_nae.fw_cache_tbl_v6[i]; if (e6->ip6.rci != ipnet->route_cache_id) continue; #ifdef IPCOM_USE_FORWARDER_VLAN if (e6->ip6.type == IPCOM_FORWARDER_PACKET_TYPE_IPV6_VLAN) { fw_cache_entry_vlan_t *ev = (fw_cache_entry_vlan_t *)e6; /* Got a player */ if (0 > ipnet_rtnetlink_fwcache_entry(param, i, IP_AF_INET6, ev->ipvlan.vlan_id, &ev->ipvlan.a.addr_v6, sizeof(ev->ipvlan.a.addr_v6), (Ip_u8 *)ev->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(ev) != 0)) goto aborted; } else if (e6->ip6.type == IPCOM_FORWARDER_PACKET_TYPE_IPV6) #endif { /* Got a player */ if (0 > ipnet_rtnetlink_fwcache_entry(param, i, IP_AF_INET6, 0, &e6->ip6.addr, sizeof(e6->ip6.addr), (Ip_u8 *)e6->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(e6) != 0)) goto aborted; } } *param->state.hash = f6_limit; } return 0; aborted: param->state.aborted = 1; *param->state.hash = (Ip_ptrdiff_t)i; return -1; } #endif #ifdef IPCOM_USE_FORWARDER_IPSEC IP_STATIC int ipnet_rtnetlink_sacache_entry(Ipnet_rtnetlink_sac_family_t *param, Ip_u32 hash_entry, int domain, Ip_u32 algid, Ip_u32 spi, void *src, void *dst) { struct Ip_nlmsghdr *nlh; struct Ip_sacmsg *sac; Ip_size_t size; nlh = ipnet_netlink_nlmsg_sz_begin(param->mem, param->nlmsg->nlmsg_seq, IP_RTM_NEWSACACHE, IP_NLM_F_MULTI); if (!nlh) return -1; sac = ipnet_netlink_sz_put(param->mem, IP_NULL, sizeof (*sac)); if (!sac) return -1; /* * Add SA message header */ sac->sac_family = (Ip_u8)domain; sac->sac_algid = (Ip_u8)algid; sac->sac_core = ipcom_nae_current_core(); sac->sac_nae = ipcom_nae_id(); sac->sac_entry = hash_entry; sac->sac_spi = spi; size = domain == IP_AF_INET ? sizeof(struct Ip_in_addr) : sizeof(struct Ip_in6_addr); /* * Put source address */ if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_SAC_SRC, size, src)) return -1; /* * Put destination address */ if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_SAC_DST, size, dst)) return -1; /* * Done */ return ipnet_netlink_nlmsg_sz_end(param->mem, nlh); } #ifdef IPCOM_USE_INET IP_STATIC int ipnet_rtnetlink_sacache_foreach_inet(Ipnet_rtnetlink_sac_family_t *param) { unsigned int i = 0; unsigned int sa_limit = ipcom_nae.fw_ipsec_entries * 2; if (*param->state.hash < sa_limit) { for (i = *param->state.hash; i < sa_limit; i++) { Ipcom_fw_ipsec_sa_t *fw_ipsec_sa; if (i >= ipcom_nae.fw_ipsec_entries) fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_dec[i - ipcom_nae.fw_ipsec_entries]; /* Input SA */ else fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_enc[i]; /* Output SA */ if (fw_ipsec_sa->cache_id != 0 && fw_ipsec_sa->domain == IP_AF_INET && !IPIPSEC_SA_MARKED_FOR_DELETION(fw_ipsec_sa)) { /* Got a player */ if (0 > ipnet_rtnetlink_sacache_entry(param, i, fw_ipsec_sa->domain, fw_ipsec_sa->algid, fw_ipsec_sa->spi, fw_ipsec_sa->src, fw_ipsec_sa->dst)) goto aborted; } } *param->state.hash = sa_limit; } return 0; aborted: param->state.aborted = 1; *param->state.hash = (Ip_ptrdiff_t)i; return -1; } #endif #ifdef IPCOM_USE_INET6 IP_STATIC int ipnet_rtnetlink_sacache_foreach_inet6(Ipnet_rtnetlink_sac_family_t *param) { unsigned int i = 0; unsigned int sa_limit = ipcom_nae.fw_ipsec_entries * 2; if (*param->state.hash < sa_limit) { for (i = *param->state.hash; i < sa_limit; i++) { Ipcom_fw_ipsec_sa_t *fw_ipsec_sa; if (i >= ipcom_nae.fw_ipsec_entries) fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_dec[i - ipcom_nae.fw_ipsec_entries]; /* Input SA */ else fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_enc[i]; /* Output SA */ if (fw_ipsec_sa->cache_id != 0 && fw_ipsec_sa->domain == IP_AF_INET6 && !IPIPSEC_SA_MARKED_FOR_DELETION(fw_ipsec_sa)) { /* Got a player */ if (0 > ipnet_rtnetlink_sacache_entry(param, i, fw_ipsec_sa->domain, fw_ipsec_sa->algid, fw_ipsec_sa->spi, fw_ipsec_sa->src, fw_ipsec_sa->dst)) goto aborted; } } *param->state.hash = sa_limit; } return 0; aborted: param->state.aborted = 1; *param->state.hash = (Ip_ptrdiff_t)i; return -1; } #endif #endif /* IPCOM_USE_FORWARDER_IPSEC */ /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *========================================================================== * ipnet_rtnetlink_fwcache_dump_family *=========================================================================== * Description: Get interface info via NETLINK * Parameters: data - Message payload. * len - Length of message. * cb - NETLINK callback entry * * Returns: 0 - Success * <0 - Failure * */ IP_GLOBAL int ipnet_rtnetlink_fwcache_dump_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlmsg, int family, Ip_ptrdiff_t *args) { Ipnet_rtnetlink_fwc_family_t param; Ip_ptrdiff_t *done = &args[0]; Ip_ptrdiff_t *s_hash = &args[1]; Ip_ptrdiff_t *s_continue = &args[2]; param.nlmsg = nlmsg; param.family = family; param.mem = mem; if (*done) goto exit_out; param.state.aborted = 0; param.state.done = done; param.state.hash = s_hash; param.state.cont = *s_continue; #ifdef IPCOM_USE_INET if (family == IP_AF_INET) ipnet_rtnetlink_fwcache_foreach_inet(¶m); #endif #ifdef IPCOM_USE_INET6 if (family == IP_AF_INET6) ipnet_rtnetlink_fwcache_foreach_inet6(¶m); #endif /* Are we aborted? */ *s_continue = param.state.aborted; /* If not aborted; we're done */ if (!param.state.aborted) *done = 1; exit_out: return param.mem->used; } IP_GLOBAL int ipnet_rtnetlink_fwcache_delfwcache_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlh, struct Ip_rtattr **rta, int family) { struct Ip_fwcmsg *fwc = IP_NLMSG_DATA(nlh); #ifdef IPCOM_USE_FORWARDER_VLAN if (IP_NULL != rta[IP_FWC_VLAN - 1]) { fw_cache_entry_vlan_t *ev = (fw_cache_entry_vlan_t *)&ipcom_nae.fw_cache_tbl_v6[fwc->fwc_entry]; if (fwc->fwc_entry >= (ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS)) return -IP_ERRNO_EINVAL; ev->ipvlan.rci = 0; return 0; } #endif #ifdef IPCOM_USE_INET if (fwc->fwc_family == IP_AF_INET) { fw_cache_entry_v4_t *e4 = &ipcom_nae.fw_cache_tbl_v4[fwc->fwc_entry]; if (fwc->fwc_entry >= (ipcom_nae_shm->fw_v4_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS)) return -IP_ERRNO_EINVAL; e4->ip4.rci = 0; return 0; } #endif #ifdef IPCOM_USE_INET6 if (fwc->fwc_family == IP_AF_INET6) { fw_cache_entry_v6_t *e6 = &ipcom_nae.fw_cache_tbl_v6[fwc->fwc_entry]; if (fwc->fwc_entry >= (ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS)) return -IP_ERRNO_EINVAL; e6->ip6.rci = 0; return 0; } #endif return -IP_ERRNO_ENOENT; } #ifdef IPCOM_USE_FORWARDER_IPSEC /* *========================================================================== * ipnet_rtnetlink_sacache_dump_family *=========================================================================== * Description: Get SA cache via NETLINK * Parameters: data - Message payload. * len - Length of message. * cb - NETLINK callback entry * * Returns: 0 - Success * <0 - Failure * */ IP_GLOBAL int ipnet_rtnetlink_sacache_dump_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlmsg, int family, Ip_ptrdiff_t *args) { Ipnet_rtnetlink_sac_family_t param; Ip_ptrdiff_t *done = &args[0]; Ip_ptrdiff_t *s_hash = &args[1]; Ip_ptrdiff_t *s_continue = &args[2]; param.nlmsg = nlmsg; param.family = family; param.mem = mem; if (*done) goto exit_out; param.state.aborted = 0; param.state.done = done; param.state.hash = s_hash; param.state.cont = *s_continue; #ifdef IPCOM_USE_INET if (family == IP_AF_INET) ipnet_rtnetlink_sacache_foreach_inet(¶m); #endif #ifdef IPCOM_USE_INET6 if (family == IP_AF_INET6) ipnet_rtnetlink_sacache_foreach_inet6(¶m); #endif /* Are we aborted? */ *s_continue = param.state.aborted; /* If not aborted; we're done */ if (!param.state.aborted) *done = 1; exit_out: return param.mem->used; } IP_GLOBAL int ipnet_rtnetlink_sacache_delsacache_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlh, struct Ip_rtattr **rta, int family) { struct Ip_sacmsg *sac = IP_NLMSG_DATA(nlh); #if defined(IPCOM_USE_INET) && defined(IPCOM_USE_INET6) if (sac->sac_family == IP_AF_INET || sac->sac_family == IP_AF_INET6) #elif defined(IPCOM_USE_INET) if (sac->sac_family == IP_AF_INET) #elif defined(IPCOM_USE_INET6) if (sac->sac_family == IP_AF_INET6) #endif { Ipcom_fw_ipsec_sa_t *fw_ipsec_sa; if (sac->sac_entry >= (ipcom_nae.fw_ipsec_entries * 2)) return -IP_ERRNO_EINVAL; else if (sac->sac_entry >= ipcom_nae.fw_ipsec_entries) fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_dec[sac->sac_entry - ipcom_nae.fw_ipsec_entries]; /* Input SA */ else fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_enc[sac->sac_entry]; /* Output SA */ ipcom_memset(fw_ipsec_sa, 0, sizeof(*fw_ipsec_sa)); return 0; } return -IP_ERRNO_ENOENT; } #endif /* IPCOM_USE_FORWARDER_IPSEC */ IP_GLOBAL int ipnet_rtnetlink_nae_setnae_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlh, struct Ip_rtattr **rta, int family) { (void) mem; (void) nlh; (void) rta; (void) family; return -IP_ERRNO_ENOSYS; } IP_GLOBAL int ipnet_rtnetlink_nae_getnae_family(Ipnet_netlink_mem_t *mem, struct Ip_nlmsghdr *nlhreq, struct Ip_rtattr **rta, int family) { struct Ip_nlmsghdr *nlh; struct Ip_naemsg *nae; Ip_u32 tmp32; Ip_u64 tmp64; unsigned long ticks; unsigned hz; int i; nlh = ipnet_netlink_nlmsg_sz_begin(mem, nlhreq->nlmsg_seq, IP_RTM_NEWNAE, 0); if (!nlh) return -1; nae = ipnet_netlink_sz_put(mem, IP_NULL, sizeof (*nae)); if (!nae) return -1; nae->nae_family = IP_AF_UNSPEC; nae->nae_id = ipcom_nae_id(); nae->nae_core = ipcom_nae_current_core(); tmp32 = (Ip_u32)ipcom_forwarder_fw_enable; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_ENABLE, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_started; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_STARTED, sizeof(Ip_u32), &tmp32)) return -1; ipcom_nae_tick_get(&ticks, &hz); tmp64 = (Ip_u64)ticks; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_TICK_COUNT, sizeof(Ip_u64), &tmp64)) return -1; tmp32 = (Ip_u32)hz; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_TICK_HZ, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_selective_invalid; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_SELECTIVE_INVALID, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_total_invalid; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_TOTAL_INVALID, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_invalid_delete; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_INVALID_DELETE, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_invalid_incomplete; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_INVALID_INCOMPLETE, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_invalid_lladdr; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_INVALID_LLADDR, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_timeout; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_TIMEOUT, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_external_delete; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_EXTERNAL, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_garbage_collect; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_GARBAGE_COLLECT, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_flushed; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_FLUSHED, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_failed; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_FAILED, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_resource; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_RESOURCE, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_entries_inet; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_CURRENT_INET, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_nae_shm->fw_v4_entries; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_TOTAL_INET, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_entries_inet6; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_CURRENT_INET6, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_nae_shm->fw_v6_entries; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_TOTAL_INET6, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_collissions; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_COLLISSIONS, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipcom_forwarder_fw_collissions_invalidate; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_COLLISSIONS_INVALIDATE, sizeof(Ip_u32), &tmp32)) return -1; tmp32 = (Ip_u32)ipnet->route_cache_id; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_ROUTE_CACHE_ID, sizeof(Ip_u32), &tmp32)) return -1; if (IP_NULL != ipcom_nae_shm_table.nae_shm_get_pkt_pool) { int pool_mtu, pool_max, pool_avail, pool_numa; char *pool_name; for (i = 0;;i++) { struct Ip_rtattr *rta_nest; if (0 > (*ipcom_nae_shm_table.nae_shm_get_pkt_pool) (i, &pool_max, &pool_avail, &pool_mtu, &pool_numa, &pool_name)) break; rta_nest = ipnet_rtnetlink_rta_sz_nested_begin(mem, IP_NAE_PKT_POOL); if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_NAME, ipcom_strlen(pool_name) + 1, pool_name)) return -1; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_MTU, sizeof(Ip_u32), &pool_mtu)) return -1; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_SIZE, sizeof(Ip_u32), &pool_max)) return -1; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_AVAIL, sizeof(Ip_u32), &pool_avail)) return -1; if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_NUMA, sizeof(Ip_u32), &pool_numa)) return -1; ipnet_rtnetlink_rta_sz_nested_end(mem, rta_nest); } } /* */ { Ipcom_forwarder_capability_t *cap_e, *cap_v; for (cap_e = IPCOM_LIST_FIRST(&ipcom_nae.capability); cap_e != IP_NULL; cap_e = IPCOM_LIST_NEXT(&cap_e->next)) { struct Ip_rtattr *rta_nest; rta_nest = ipnet_rtnetlink_rta_sz_nested_begin(mem, IP_NAE_CAPABILITY); if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_NAME, ipcom_strlen(cap_e->cap) + 1, cap_e->cap)) return -1; for (cap_v = IPCOM_LIST_FIRST(&cap_e->values); cap_v != IP_NULL; cap_v = IPCOM_LIST_NEXT(&cap_v->next)) if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_CAPABILITY_VALUE, ipcom_strlen(cap_v->cap) + 1, cap_v->cap)) return -1; ipnet_rtnetlink_rta_sz_nested_end(mem, rta_nest); } } /* * Done */ return ipnet_netlink_nlmsg_sz_end(mem, nlh); } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ #endif /* IPNET_USE_NETLINK */ /* **************************************************************************** * END OF FILE **************************************************************************** */