t_std_error nas_os_util_int_admin_state_get(const char *name, db_interface_state_t *state, db_interface_operational_state_t *ostate) { struct ifreq ifr; strncpy(ifr.ifr_ifrn.ifrn_name,name,sizeof(ifr.ifr_ifrn.ifrn_name)-1); int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock==-1) return STD_ERR(INTERFACE,FAIL,errno); t_std_error err = STD_ERR_OK; do { if (ioctl(sock, SIOCGIFFLAGS, &ifr) >= 0) { *state = (ifr.ifr_flags & IFF_UP) ? DB_ADMIN_STATE_UP : DB_ADMIN_STATE_DN; if (ostate!=NULL) { *ostate = (ifr.ifr_flags & IFF_RUNNING) ? DB_OPER_STATE_UP : DB_OPER_STATE_DN; } break; } err = STD_ERR(INTERFACE,FAIL,errno); EV_LOG_ERRNO(ev_log_t_INTERFACE,3,"DB-LINUX-GET",STD_ERR_EXT_PRIV(err)); } while(0); close(sock); return err; }
t_std_error nas_os_util_int_admin_state_set(const char *name, db_interface_state_t state, db_interface_operational_state_t ostate) { struct ifreq ifr; strncpy(ifr.ifr_ifrn.ifrn_name,name,sizeof(ifr.ifr_ifrn.ifrn_name)-1); int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock==-1) return STD_ERR(INTERFACE,FAIL,errno); t_std_error err = STD_ERR_OK; do { if (ioctl(sock, SIOCGIFFLAGS, &ifr) >= 0) { if (state == DB_ADMIN_STATE_UP) { ifr.ifr_flags |= IFF_UP; } else { ifr.ifr_flags &= ~IFF_UP; } if (ioctl(sock, SIOCSIFFLAGS, &ifr) >=0) { break; } } err = STD_ERR(INTERFACE,FAIL,errno); EV_LOG_ERRNO(ev_log_t_INTERFACE,3,"DB-LINUX-SET",STD_ERR_EXT_PRIV(err)); } while(0); close(sock); return err; }
t_std_error nas_os_util_int_mac_addr_get(const char *name, hal_mac_addr_t *macAddr) { struct ifreq ifr; strncpy(ifr.ifr_ifrn.ifrn_name,name,sizeof(ifr.ifr_ifrn.ifrn_name)-1); int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock==-1) return STD_ERR(INTERFACE,FAIL,errno); t_std_error err = STD_ERR_OK; do { ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; if (ioctl(sock, SIOCGIFHWADDR, &ifr) >= 0) { memcpy(*macAddr, ifr.ifr_hwaddr.sa_data,sizeof(*macAddr)); break; } err = STD_ERR(INTERFACE,FAIL,errno); EV_LOG_ERRNO(ev_log_t_INTERFACE,3,"DB-LINUX-SET",STD_ERR_EXT_PRIV(err)); } while (0); close(sock); return err; }
t_std_error nas_os_util_int_mtu_get(const char *name, unsigned int *mtu) { struct ifreq ifr; strncpy(ifr.ifr_ifrn.ifrn_name,name,sizeof(ifr.ifr_ifrn.ifrn_name)-1); int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock==-1) return STD_ERR(INTERFACE,FAIL,errno); t_std_error err = STD_ERR_OK; do { if (ioctl(sock, SIOCGIFMTU, &ifr) >= 0) { *mtu = (ifr.ifr_mtu ) ; break; } err = STD_ERR(INTERFACE,FAIL,errno); EV_LOG_ERRNO(ev_log_t_INTERFACE,3,"DB-LINUX-GET",STD_ERR_EXT_PRIV(err)); } while(0); close(sock); return err; }
cps_api_return_code_t nas_os_update_neighbor(cps_api_object_t obj, msg_type m_type) { static char buff[NL_RT_MSG_BUFFER_LEN]; hal_mac_addr_t mac_addr; char addr_str[INET6_ADDRSTRLEN]; memset(buff,0,sizeof(buff)); memset(mac_addr, 0, sizeof(mac_addr)); cps_api_object_attr_t ip = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_ADDRESS); cps_api_object_attr_t af = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_AF); cps_api_object_attr_t mac = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_MAC_ADDR); cps_api_object_attr_t if_index = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_IFINDEX); cps_api_object_attr_t nbr_type = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_TYPE); if (ip == CPS_API_ATTR_NULL || af == CPS_API_ATTR_NULL || if_index == CPS_API_ATTR_NULL || (m_type != NAS_RT_DEL && mac == CPS_API_ATTR_NULL)) { EV_LOG(ERR, NAS_OS, ev_log_s_CRITICAL, "NEIGH-UPD", "Missing neighbor params"); return cps_api_ret_code_ERR; } struct nlmsghdr *nlh = (struct nlmsghdr *) nlmsg_reserve((struct nlmsghdr *)buff,sizeof(buff),sizeof(struct nlmsghdr)); struct ndmsg * ndm = (struct ndmsg *) nlmsg_reserve(nlh,sizeof(buff),sizeof(struct ndmsg)); ndm->ndm_ifindex = cps_api_object_attr_data_u32(if_index); ndm->ndm_family = (unsigned char) cps_api_object_attr_data_u32(af); if (nbr_type != CPS_API_ATTR_NULL) { if (((unsigned char) cps_api_object_attr_data_u32(nbr_type)) == BASE_ROUTE_RT_TYPE_STATIC){ /* Static ARP handling */ ndm->ndm_state = NUD_PERMANENT; /* Set this flag to replace the dynamic ARP to static if exists */ if (m_type == NAS_RT_ADD) m_type = NAS_RT_SET; }else{ ndm->ndm_state = NUD_REACHABLE; } } else { /* if NH type is not given, assume the state as permanent */ ndm->ndm_state = NUD_PERMANENT; /* Set this flag to replace the dynamic ARP to static if exists */ if (m_type == NAS_RT_ADD) m_type = NAS_RT_SET; } uint16_t flags = nas_os_get_nl_flags(m_type); uint16_t type = (m_type == NAS_RT_DEL)?RTM_DELNEIGH:RTM_NEWNEIGH; nas_os_pack_nl_hdr(nlh, type, flags); ndm->ndm_type = RTN_UNICAST; uint32_t addr_len = (ndm->ndm_family == AF_INET)?HAL_INET4_LEN:HAL_INET6_LEN; nlmsg_add_attr(nlh,sizeof(buff),NDA_DST,cps_api_object_attr_data_bin(ip),addr_len); if (mac != CPS_API_ATTR_NULL) { void * data = cps_api_object_attr_data_bin(mac); memcpy(mac_addr,data,sizeof(mac_addr)); nlmsg_add_attr(nlh,sizeof(buff),NDA_LLADDR, &mac_addr, HAL_MAC_ADDR_LEN); } t_std_error rc = nl_do_set_request(nas_nl_sock_T_NEI,nlh,buff,sizeof(buff)); int err_code = STD_ERR_EXT_PRIV (rc); EV_LOG(INFO, NAS_OS, 2,"NEIGH-UPD","Operation:%s family:%s NH:%s MAC:%s out-intf:%d state:%s rc:%d", ((m_type == NAS_RT_DEL) ? "Arp-Del" : "Arp-Add"), ((ndm->ndm_family == AF_INET) ? "IPv4" : "IPv6"), ((ndm->ndm_family == AF_INET) ? (inet_ntop(ndm->ndm_family, cps_api_object_attr_data_bin(ip), addr_str, INET_ADDRSTRLEN)) : (inet_ntop(ndm->ndm_family, cps_api_object_attr_data_bin(ip), addr_str, INET6_ADDRSTRLEN))), nl_neigh_mac_to_str(&mac_addr), ndm->ndm_ifindex, ((ndm->ndm_state == NUD_REACHABLE) ? "Dynamic" : "Static"), err_code); return rc; }
cps_api_return_code_t nas_os_update_route (cps_api_object_t obj, msg_type m_type) { static char buff[NL_RT_MSG_BUFFER_LEN]; // Allocate from DS char addr_str[INET6_ADDRSTRLEN]; memset(buff,0,sizeof(buff)); cps_api_object_attr_t prefix = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_ROUTE_PREFIX); cps_api_object_attr_t af = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_AF); cps_api_object_attr_t nh_count = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_NH_COUNT); cps_api_object_attr_t pref_len = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_PREFIX_LEN); if (prefix == CPS_API_ATTR_NULL || af == CPS_API_ATTR_NULL || pref_len == CPS_API_ATTR_NULL || (m_type != NAS_RT_DEL && nh_count == CPS_API_ATTR_NULL)) { EV_LOG(ERR, NAS_OS, ev_log_s_CRITICAL, "ROUTE-UPD", "Missing route params"); return cps_api_ret_code_ERR; } struct nlmsghdr *nlh = (struct nlmsghdr *) nlmsg_reserve((struct nlmsghdr *)buff,sizeof(buff),sizeof(struct nlmsghdr)); struct rtmsg * rm = (struct rtmsg *) nlmsg_reserve(nlh,sizeof(buff),sizeof(struct rtmsg)); uint16_t flags = nas_os_get_nl_flags(m_type); uint16_t type = (m_type == NAS_RT_DEL)?RTM_DELROUTE:RTM_NEWROUTE; nas_os_pack_nl_hdr(nlh, type, flags); rm->rtm_table = RT_TABLE_MAIN; rm->rtm_protocol = RTPROT_UNSPEC; // This could be assigned to correct owner in future /* For route delete, initialize scope to no-where and * this will get updated to link when Nh addr/ifx is provided. */ if (type != RTM_DELROUTE) rm->rtm_scope = RT_SCOPE_UNIVERSE; else rm->rtm_scope = RT_SCOPE_NOWHERE; rm->rtm_type = RTN_UNICAST; rm->rtm_dst_len = cps_api_object_attr_data_u32(pref_len); rm->rtm_family = (unsigned char) cps_api_object_attr_data_u32(af); uint32_t addr_len = (rm->rtm_family == AF_INET)?HAL_INET4_LEN:HAL_INET6_LEN; nlmsg_add_attr(nlh,sizeof(buff),RTA_DST,cps_api_object_attr_data_bin(prefix),addr_len); uint32_t nhc = 0; if (nh_count != CPS_API_ATTR_NULL) nhc = cps_api_object_attr_data_u32(nh_count); EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","NH count:%d family:%s msg:%s for prefix:%s len:%d scope:%d", nhc, ((rm->rtm_family == AF_INET) ? "IPv4" : "IPv6"), ((m_type == NAS_RT_ADD) ? "Route-Add" : ((m_type == NAS_RT_DEL) ? "Route-Del" : "Route-Set")), ((rm->rtm_family == AF_INET) ? (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(prefix), addr_str, INET_ADDRSTRLEN)) : (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(prefix), addr_str, INET6_ADDRSTRLEN))), rm->rtm_dst_len, rm->rtm_scope); if (nhc == 1) { cps_api_attr_id_t ids[3] = { BASE_ROUTE_OBJ_ENTRY_NH_LIST, 0, BASE_ROUTE_OBJ_ENTRY_NH_LIST_NH_ADDR}; const int ids_len = sizeof(ids)/sizeof(*ids); cps_api_object_attr_t gw = cps_api_object_e_get(obj,ids,ids_len); if (gw != CPS_API_ATTR_NULL) { nlmsg_add_attr(nlh,sizeof(buff),RTA_GATEWAY,cps_api_object_attr_data_bin(gw),addr_len); rm->rtm_scope = RT_SCOPE_UNIVERSE; // set scope to universe when gateway is specified EV_LOG(INFO, NAS_OS, 2,"ROUTE-UPD","NH:%s scope:%d", ((rm->rtm_family == AF_INET) ? (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(gw), addr_str, INET_ADDRSTRLEN)) : (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(gw), addr_str, INET6_ADDRSTRLEN))), rm->rtm_scope); } else { EV_LOG(INFO, NAS_OS, ev_log_s_MINOR, "ROUTE-UPD", "Missing Gateway, could be intf route"); /* * This could be an interface route, do not return from here! */ } ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_IFINDEX; cps_api_object_attr_t gwix = cps_api_object_e_get(obj,ids,ids_len); if (gwix != CPS_API_ATTR_NULL) { if (gw == CPS_API_ATTR_NULL) { rm->rtm_scope = RT_SCOPE_LINK; } EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","out-intf: %d scope:%d", (int)cps_api_object_attr_data_u32(gwix), rm->rtm_scope); nas_nl_add_attr_int(nlh,sizeof(buff),RTA_OIF,gwix); } ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_WEIGHT; cps_api_object_attr_t weight = cps_api_object_e_get(obj,ids,ids_len); if (weight != CPS_API_ATTR_NULL) nas_nl_add_attr_int(nlh,sizeof(buff),RTA_PRIORITY,weight); } else if (nhc > 1){ struct nlattr * attr_nh = nlmsg_nested_start(nlh, sizeof(buff)); attr_nh->nla_len = 0; attr_nh->nla_type = RTA_MULTIPATH; size_t ix = 0; for (ix = 0; ix < nhc ; ++ix) { struct rtnexthop * rtnh = (struct rtnexthop * )nlmsg_reserve(nlh,sizeof(buff), sizeof(struct rtnexthop)); memset(rtnh,0,sizeof(*rtnh)); cps_api_attr_id_t ids[3] = { BASE_ROUTE_OBJ_ENTRY_NH_LIST, ix, BASE_ROUTE_OBJ_ENTRY_NH_LIST_NH_ADDR}; const int ids_len = sizeof(ids)/sizeof(*ids); cps_api_object_attr_t attr = cps_api_object_e_get(obj,ids,ids_len); if (attr != CPS_API_ATTR_NULL) { nlmsg_add_attr(nlh,sizeof(buff),RTA_GATEWAY, cps_api_object_attr_data_bin(attr),addr_len); rm->rtm_scope = RT_SCOPE_UNIVERSE; // set scope to universe when gateway is specified EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","MP-NH:%d %s scope:%d",ix, ((rm->rtm_family == AF_INET) ? (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(attr), addr_str, INET_ADDRSTRLEN)) : (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(attr), addr_str, INET6_ADDRSTRLEN))), rm->rtm_scope); } else { EV_LOG(ERR, NAS_OS, ev_log_s_CRITICAL, "ROUTE-UPD", "Error - Missing Gateway"); return cps_api_ret_code_ERR; } ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_IFINDEX; attr = cps_api_object_e_get(obj,ids,ids_len); if (attr != CPS_API_ATTR_NULL) rtnh->rtnh_ifindex = (int)cps_api_object_attr_data_u32(attr); ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_WEIGHT; attr = cps_api_object_e_get(obj,ids,ids_len); if (attr != CPS_API_ATTR_NULL) rtnh->rtnh_hops = (char)cps_api_object_attr_data_u32(attr); rtnh->rtnh_len = (char*)nlmsg_tail(nlh) - (char*)rtnh; } nlmsg_nested_end(nlh,attr_nh); } t_std_error rc = nl_do_set_request(nas_nl_sock_T_ROUTE,nlh,buff,sizeof(buff)); int err_code = STD_ERR_EXT_PRIV (rc); EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","Netlink error_code %d", err_code); /* * Return success if the error is exist, in case of addition, or * no-exist, in case of deletion. This is because, kernel might have * deleted the route entries (when interface goes down) but has not sent netlink * events for those routes and RTM is trying to delete after that. * Similarly, during ip address configuration, kernel may add the routes * before RTM tries to configure kernel. * */ if(err_code == ESRCH || err_code == EEXIST ) { EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","No such process or Entry already exists"); /* * Kernel may or may not have the routes but NAS routing needs to be informed * as is from kernel netlink to program NPU for the route addition/deletion to * ensure stale routes are cleaned */ if(err_code == ESRCH) nas_os_publish_route(RTM_DELROUTE, obj); else nas_os_publish_route(RTM_NEWROUTE, obj); rc = STD_ERR_OK; } return rc; }
/** PAS Daemon thermal_sensor read interface */ int dn_pas_fuse_thermal_sensor_read( dev_node_t *node, char *buf, size_t size, off_t offset ) { int res = -ENOTSUP; size_t len = 0; char trans_buf[FUSE_FILE_DEFAULT_SIZE] = { 0 }; memset(buf, 0, size); /** check for node & buffer validity */ if ((NULL == node) || (NULL == buf)) { return res; } /** switch on type of file to be read */ switch (node->fuse_filetype) { /** alias */ case FUSE_THERMAL_SENSOR_FILETYPE_ALIAS: { const char *alias_name; if (NULL != (alias_name = sdi_resource_alias_get(node->fuse_resource_hdl))) { dn_pas_fuse_print(trans_buf, FUSE_FILE_DEFAULT_SIZE, &len, &res, "%-25s : %s", "Alias", (char *) alias_name); } break; } /** temperature value read */ case FUSE_THERMAL_SENSOR_FILETYPE_TEMPERATURE: { int temperature; if (STD_ERR_OK == sdi_temperature_get(node->fuse_resource_hdl, &temperature)) { dn_pas_fuse_print(trans_buf, FUSE_FILE_DEFAULT_SIZE, &len, &res, "%-25s : %i deg C", "Temperature", temperature); } break; } /** low threshold value read */ case FUSE_THERMAL_SENSOR_FILETYPE_LOW_THRESHOLD: { int threshold; if (STD_ERR_OK == sdi_temperature_threshold_get(node->fuse_resource_hdl, SDI_LOW_THRESHOLD, &threshold)) { dn_pas_fuse_print(trans_buf, FUSE_FILE_DEFAULT_SIZE, &len, &res, "%-25s : %i deg C", "Low Threshold", threshold); } break; } /** high threshold value read */ case FUSE_THERMAL_SENSOR_FILETYPE_HIGH_THRESHOLD: { int threshold; if (STD_ERR_OK == sdi_temperature_threshold_get(node->fuse_resource_hdl, SDI_HIGH_THRESHOLD, &threshold)) { dn_pas_fuse_print(trans_buf, FUSE_FILE_DEFAULT_SIZE, &len, &res, "%-25s : %i deg C", "High Threshold", threshold); } break; } /** critical threshold value read */ case FUSE_THERMAL_SENSOR_FILETYPE_CRITICAL_THRESHOLD: { int threshold; t_std_error err; if ((err = sdi_temperature_threshold_get(node->fuse_resource_hdl, SDI_CRITICAL_THRESHOLD, &threshold)) == STD_ERR_OK) { dn_pas_fuse_print(trans_buf, FUSE_FILE_DEFAULT_SIZE, &len, &res, "%-25s : %i deg C", "Critical Threshold", threshold); } else if (STD_ERR_EXT_PRIV(err) == ENOTSUP) { res = -ENOTSUP; } break; } /** fault status value read */ case FUSE_THERMAL_SENSOR_FILETYPE_ALERT_ON: { bool alert = false; if (STD_ERR_OK == sdi_temperature_status_get(node->fuse_resource_hdl, &alert)) { dn_pas_fuse_print(trans_buf, FUSE_FILE_DEFAULT_SIZE, &len, &res, "%-25s : %s", "Alert", alert ? "on" : "off"); } break; } /** diagnostic mode */ case FUSE_THERMAL_SENSOR_FILETYPE_DIAG_MODE: { dn_pas_fuse_print(trans_buf, FUSE_FILE_DEFAULT_SIZE, &len, &res, "%-25s : %s", "Diagnostic Mode", (dn_pald_diag_mode_get() ? "up" : "down")); break; } default: { if(node->fuse_filetype >= FUSE_THERMAL_SENSOR_FILETYPE_MIN && node->fuse_filetype < FUSE_THERMAL_SENSOR_FILETYPE_MAX) { res = -EPERM; } else { res = -ENOENT; } break; } } if (offset < len) { size = dn_pas_fuse_calc_size(len, size, offset); memcpy(buf, &trans_buf[offset], size); res = size; } return res; }