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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}