shared_ptr<Interface> ThriftConfigApplier::updateInterface(
    const shared_ptr<Interface>& orig,
    const cfg::Interface* config,
    const Interface::Addresses& addrs) {
    CHECK_EQ(orig->getID(), config->intfID);

    cfg::NdpConfig ndp;
    if (config->__isset.ndp) {
        ndp = config->ndp;
    }
    auto name = getInterfaceName(config);
    auto mac = getInterfaceMac(config);
    auto mtu = config->__isset.mtu ? config->mtu : Interface::kDefaultMtu;
    if (orig->getRouterID() == RouterID(config->routerID) &&
            orig->getVlanID() == VlanID(config->vlanID) &&
            orig->getName() == name &&
            orig->getMac() == mac &&
            orig->getAddresses() == addrs &&
            orig->getNdpConfig() == ndp &&
            orig->getMtu() == mtu) {
        // No change
        return nullptr;
    }

    auto newIntf = orig->clone();
    newIntf->setRouterID(RouterID(config->routerID));
    newIntf->setVlanID(VlanID(config->vlanID));
    newIntf->setName(name);
    newIntf->setMac(mac);
    newIntf->setAddresses(addrs);
    newIntf->setNdpConfig(ndp);
    newIntf->setMtu(mtu);
    return newIntf;
}
shared_ptr<Interface> ThriftConfigApplier::createInterface(
    const cfg::Interface* config,
    const Interface::Addresses& addrs) {
    auto name = getInterfaceName(config);
    auto mac = getInterfaceMac(config);
    auto mtu = config->__isset.mtu ? config->mtu : Interface::kDefaultMtu;
    auto intf = make_shared<Interface>(InterfaceID(config->intfID),
                                       RouterID(config->routerID),
                                       VlanID(config->vlanID),
                                       name,
                                       mac,
                                       mtu);
    intf->setAddresses(addrs);
    if (config->__isset.ndp) {
        intf->setNdpConfig(config->ndp);
    }
    return intf;
}
Example #3
0
int getSenderInterface(unsigned int targetIP, char* device, char* mac)
{
    struct nlmsghdr* nlMsg;

    char               msgBuf[BUFSIZE];

    int sock;
    ssize_t len = 0;
    uint32_t msgSeq = 0;

    if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
    {
        syslog(LOG_ERR, "unable to create socket: '%s'", strerror(errno));
        return -1;
    }

    memset(msgBuf, 0, BUFSIZE);

    nlMsg = (struct nlmsghdr *)msgBuf;
    nlMsg->nlmsg_len   = NLMSG_LENGTH(sizeof(struct rtmsg));
    nlMsg->nlmsg_type  = RTM_GETROUTE;
    nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
    nlMsg->nlmsg_seq   = msgSeq++;
    nlMsg->nlmsg_pid   = getpid();

    if (send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0)
    {
        syslog(LOG_ERR, "unable to write to socket: '%s'", strerror(errno));
        close(sock);
        return -1;
    }

    if ((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0)
    {
        syslog(LOG_ERR, "unable to read from socket: '%s'", strerror(errno));
        close(sock);
        return -1;
    }

    for (; nlmsg_ok(nlMsg, len); nlMsg = NLMSG_NEXT(nlMsg, len)) {
        struct rtmsg*  rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);

        if (rtMsg->rtm_family == AF_INET || rtMsg->rtm_table == RT_TABLE_MAIN)
        {
            struct rtattr* rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
            int            rtLen  = RTM_PAYLOAD(nlMsg);
            char           ifName[IF_NAMESIZE] = {0};
            unsigned int   dstAddr = 0, dstMask = 1;
            for (; RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen)) {
                switch (rtAttr->rta_type)
                {
                    case RTA_OIF:
                        if_indextoname(*(int *)RTA_DATA(rtAttr), ifName);
                        break;
                    case RTA_DST:
                        dstAddr = *(u_int *)RTA_DATA(rtAttr);
                        dstMask = rtLen;
                        break;
                }
            }
            if (dstMask <= 32)
            {
                dstMask = htonl(ntohl(inet_addr("255.255.255.255")) << (32 - dstMask));
                if ((dstAddr & dstMask) == (targetIP & dstMask))
                {
                    if (getInterfaceMac(ifName, mac) == 0)
                    {
                        close(sock);
                        snprintf(device, IFNAMSIZ, "%s", ifName);
                        syslog(LOG_INFO, "sending from device '%s' with MAC address '%s'",
                                device,
                                printMACStr(mac));
                        return 0;
                    }
                }
            }
        }
    }
    close(sock);
    return 1;
}