Esempio n. 1
0
extern "C" bool nl_get_ip_info (int rt_msg_type, struct nlmsghdr *hdr, cps_api_object_t obj) {

    struct ifaddrmsg *ifmsg = (struct ifaddrmsg *)NLMSG_DATA(hdr);

    if(hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifmsg)))
        return false;

    typedef enum { IP_KEY, IFINDEX, PREFIX, ADDRESS, IFNAME } attr_t ;
    static const std::map<uint32_t, std::map<int,cps_api_attr_id_t>> _ipmap = {
      {AF_INET,
      {
        {IP_KEY,  BASE_IP_IPV4_OBJ},
        {IFINDEX, BASE_IP_IPV4_IFINDEX},
        {PREFIX,  BASE_IP_IPV4_ADDRESS_PREFIX_LENGTH},
        {ADDRESS, BASE_IP_IPV4_ADDRESS_IP},
        {IFNAME,  BASE_IP_IPV4_NAME}
      }},

      {AF_INET6,
      {
        {IP_KEY,  BASE_IP_IPV6_OBJ},
        {IFINDEX, BASE_IP_IPV6_IFINDEX},
        {PREFIX,  BASE_IP_IPV6_ADDRESS_PREFIX_LENGTH},
        {ADDRESS, BASE_IP_IPV6_ADDRESS_IP},
        {IFNAME,  BASE_IP_IPV6_NAME}
      }}
    };

    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),_ipmap.at(ifmsg->ifa_family).at(IP_KEY),
                                    cps_api_qualifier_TARGET);

    cps_api_set_key_data(obj,_ipmap.at(ifmsg->ifa_family).at(IFINDEX), cps_api_object_ATTR_T_U32,
                         &ifmsg->ifa_index,sizeof(ifmsg->ifa_index));

    cps_api_object_attr_add_u32(obj, _ipmap.at(ifmsg->ifa_family).at(IFINDEX), ifmsg->ifa_index);
    cps_api_object_attr_add_u32(obj, _ipmap.at(ifmsg->ifa_family).at(PREFIX), ifmsg->ifa_prefixlen);

    int nla_len = nlmsg_attrlen(hdr,sizeof(*ifmsg));
    struct nlattr *head = nlmsg_attrdata(hdr, sizeof(struct ifaddrmsg));

    struct nlattr *attrs[__IFLA_MAX];
    memset(attrs,0,sizeof(attrs));

    if (nla_parse(attrs,__IFLA_MAX,head,nla_len)!=0) {
        EV_LOG_TRACE(ev_log_t_NAS_OS,ev_log_s_WARNING,"IP-NL-PARSE","Failed to parse attributes");
        cps_api_object_delete(obj);
        return false;
    }

    if(attrs[IFA_ADDRESS]!=NULL) {
       rta_add_ip((struct nlattr*)ifmsg, ifmsg->ifa_family,
                   obj, _ipmap.at(ifmsg->ifa_family).at(ADDRESS));
    }

    if(attrs[IFA_LABEL]!=NULL) {
      rta_add_name(attrs[IFA_LABEL], obj, _ipmap.at(ifmsg->ifa_family).at(IFNAME));
    }


    if (rt_msg_type == RTM_NEWADDR)  {
        cps_api_object_set_type_operation(cps_api_object_key(obj),cps_api_oper_CREATE);
    } else if (rt_msg_type == RTM_DELADDR)  {
        cps_api_object_set_type_operation(cps_api_object_key(obj),cps_api_oper_DELETE);
    } else {
        cps_api_object_set_type_operation(cps_api_object_key(obj),cps_api_oper_SET);
    }

    return true;
}
Esempio n. 2
0
//db_if_event_t
bool nl_get_if_info (int rt_msg_type, struct nlmsghdr *hdr, cps_api_object_t obj) {

    struct ifinfomsg *ifmsg = (struct ifinfomsg *)NLMSG_DATA(hdr);

    if(hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifmsg)))
        return false;

    db_if_type_t _type = DB_IF_TYPE_PHYS_INTER;
    uint_t ifindex = ifmsg->ifi_index;
    uint32_t op = 0;

    EV_LOG(INFO, NAS_OS, 3, "NET-MAIN", "nl_get_if_info msgType %d, ifindex %d change %x\n",
           rt_msg_type, ifindex, ifmsg->ifi_change);

    if (rt_msg_type ==RTM_NEWLINK)  {
        op = DB_INTERFACE_OP_CREATE;
    } else if (rt_msg_type ==RTM_DELLINK)  {
        op = DB_INTERFACE_OP_DELETE;
    } else {
        op = DB_INTERFACE_OP_SET;
    }
    cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_OPERATION,op);
    cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_FLAGS, ifmsg->ifi_flags);

    cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_IFINDEX,ifindex);

    if(ifmsg->ifi_flags & IFF_UP) {
        cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_ADMIN_STATE,DB_ADMIN_STATE_UP);
    } else {
        cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_ADMIN_STATE,DB_ADMIN_STATE_DN);
    }

    int nla_len = nlmsg_attrlen(hdr,sizeof(*ifmsg));
    struct nlattr *head = nlmsg_attrdata(hdr, sizeof(struct ifinfomsg));

    struct nlattr *attrs[__IFLA_MAX];
    memset(attrs,0,sizeof(attrs));

    if (nla_parse(attrs,__IFLA_MAX,head,nla_len)!=0) {
        EV_LOG(ERR,NAS_OS,0,"NL-PARSE","Failed to parse attributes");
        cps_api_object_delete(obj);
        return false;
    }

    if (attrs[IFLA_ADDRESS]!=NULL) {
        rta_add_mac(attrs[IFLA_ADDRESS],obj,cps_api_if_STRUCT_A_IF_MACADDR);
    }
    if(attrs[IFLA_IFNAME]!=NULL) {
        rta_add_name(attrs[IFLA_IFNAME],obj,cps_api_if_STRUCT_A_NAME);
    }

    if(attrs[IFLA_MTU]!=NULL) {
        int *mtu = (int *) nla_data(attrs[IFLA_MTU]);
        cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_MTU,(*mtu + NAS_LINK_MTU_HDR_SIZE));
    }

    if(attrs[IFLA_MASTER]!=NULL) {
            /* This gives us the bridge index, which should be sent to
             * NAS for correlation  */
        EV_LOG(INFO, NAS_OS, 3, "NET-MAIN", "Rcvd master index %d",
                *(int *)nla_data(attrs[IFLA_MASTER]));

        cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_MASTER,
                                   *(int *)nla_data(attrs[IFLA_MASTER]));
        if(op == DB_INTERFACE_OP_DELETE) {
            /* With Dell offering VLAN data structures use port index instead of
             * vlan interface */
            int phy_ifindex = 0;
            nas_os_physical_to_vlan_ifindex(ifindex, 0, false, &phy_ifindex);
            cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_IFINDEX, phy_ifindex);
            cps_api_object_attr_add_u32(obj, cps_api_if_STRUCT_A_VLAN_PORT_INDEX, ifindex);
            _type = DB_IF_TYPE_VLAN_INTER;
        }
    }

    struct nlattr *linkinfo[IFLA_INFO_MAX];
    struct nlattr *vlan[IFLA_VLAN_MAX];
    char *info_kind;

    if (attrs[IFLA_LINKINFO]) {
        memset(linkinfo,0,sizeof(linkinfo));
        nla_parse_nested(linkinfo,IFLA_INFO_MAX,attrs[IFLA_LINKINFO]);

        if(linkinfo[IFLA_INFO_KIND]) {
            info_kind = (char *)nla_data(linkinfo[IFLA_INFO_KIND]);
            EV_LOG(INFO, NAS_OS, 3, "NET-MAIN", "In IFLA_INFO_KIND for %s index %d",
                   info_kind, ifindex);

            if(!strncmp(info_kind, "vlan", 4)) {
                if(attrs[IFLA_MASTER]!=NULL) {
                    if (linkinfo[IFLA_INFO_DATA]) {
                        memset(vlan,0,sizeof(vlan));

                        nla_parse_nested(vlan,IFLA_VLAN_MAX,linkinfo[IFLA_INFO_DATA]);
                        if (vlan[IFLA_VLAN_ID]) {
                            EV_LOG(INFO, NAS_OS, 3, "NET-MAIN", "Received VLAN %d",
                                   ifindex);
                            cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_VLAN_ID,
                                                    *(uint16_t*)nla_data(vlan[IFLA_VLAN_ID]));
                            _type = DB_IF_TYPE_VLAN_INTER;

                            if (attrs[IFLA_LINK]) {
                                //port that is added to vlan
                                uint32_t portIndex = *(uint32_t*)nla_data(attrs[IFLA_LINK]);

                                if (op == DB_INTERFACE_OP_DELETE) {
                                    cps_api_object_attr_add_u32(obj, cps_api_if_STRUCT_A_VLAN_PORT_INDEX, ifindex);
                                } else {
                                    cps_api_object_attr_add_u32(obj, cps_api_if_STRUCT_A_VLAN_PORT_INDEX,
                                        portIndex);
                                }
                            } //IFLA_LINK
                        } //IFLA_VLAN_ID
                    }//IFLA_INFO_DATA
                }// IFLA_MASTER
            } // vlan interface
            else if(!strncmp(info_kind, "tun", 3)) {
                /* TODO : Revisit this and introduce a logical interface type */
                 if(attrs[IFLA_MASTER]!=NULL) {
                     EV_LOG(INFO, NAS_OS,3, "NET-MAIN", "Received tun %d",
                                ifindex);

                     _type = DB_IF_TYPE_VLAN_INTER;
                      cps_api_object_attr_add_u32(obj, cps_api_if_STRUCT_A_VLAN_PORT_INDEX,
                                                  ifindex);
                 }

                 if(ifmsg->ifi_flags & IFF_SLAVE)
                 {
                     EV_LOG(INFO, NAS_OS,3, "NET-MAIN", "Received tun %d and state IFF_UP",
                             ifindex,ifmsg->ifi_flags);
                     _type = DB_IF_TYPE_LAG_INTER;
                 }
            }
            else if(!strncmp(info_kind, "bridge", 6)) {

                EV_LOG(INFO,NAS_OS,3, "NET-MAIN", "Bridge intf index is %d ",
                            ifindex);
                _type = DB_IF_TYPE_BRIDGE_INTER;
            } /* bridge interface */
            else if(!strncmp(info_kind, "bond", 4)) {
                EV_LOG(INFO, NAS_OS,3, "NET-MAIN", "Bond interface index is %d ",
                            ifindex);
                _type = DB_IF_TYPE_LAG_INTER;

                if(attrs[IFLA_MASTER]!=NULL) {
                    EV_LOG(INFO, NAS_OS,3, "NET-MAIN", "Received bond %d with master set %d",
                               ifindex, *(int *)nla_data(attrs[IFLA_MASTER]));

                    /* Bond with master set, means configured in a bridge
                     * Pass the master index as the ifindex for vlan processing to continue */
                    _type = DB_IF_TYPE_VLAN_INTER;

                    cps_api_object_attr_add_u32(obj, cps_api_if_STRUCT_A_VLAN_PORT_INDEX,
                                                ifindex);
                    if (op == DB_INTERFACE_OP_DELETE ) {
                        cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_IFINDEX,
                            *(int *)nla_data(attrs[IFLA_MASTER]));
                    }
                }
            } // bond interface
        }
    }

    if(attrs[IFLA_OPERSTATE]!=NULL) {
        int *link = (int *) nla_data(attrs[IFLA_OPERSTATE]);
        if (*link==IF_OPER_UP) {
            cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_OPER_STATE,DB_OPER_STATE_UP);
        } else if (*link==IF_OPER_DOWN) {
            cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_OPER_STATE,DB_OPER_STATE_DN);
        }
    }

    cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_IF_TYPE,_type);

    cps_api_int_if_key_create(cps_api_object_key(obj),true,0,ifindex);

    return true;
}