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; }
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; }