From: Tomek Mrugalski Date: Tue, 21 Feb 2012 15:56:58 +0000 (+0100) Subject: [1528] nlmsg_list converted to C++ style. X-Git-Tag: trac2351_base~240^2~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f9ddb4963264b1ac022e7d550930dfbc825d71c;p=thirdparty%2Fkea.git [1528] nlmsg_list converted to C++ style. --- diff --git a/src/lib/dhcp/iface_mgr_linux.cc b/src/lib/dhcp/iface_mgr_linux.cc index 8b19c2716f..21ec297c51 100644 --- a/src/lib/dhcp/iface_mgr_linux.cc +++ b/src/lib/dhcp/iface_mgr_linux.cc @@ -28,27 +28,24 @@ using namespace isc; using namespace isc::asiolink; using namespace isc::dhcp; +typedef vector NetlinkMessages; + /// This is a structure that defines context for netlink connection. struct rtnl_handle { - int fd; + int fd; // netlink file descriptor struct sockaddr_nl local; struct sockaddr_nl peer; - __u32 seq; - __u32 dump; + __u32 seq; + __u32 dump; }; -struct nlmsg_list -{ - struct nlmsg_list *next; - struct nlmsghdr h; -}; - -const int sndbuf = 32768; -const int rcvbuf = 32768; +const size_t sndbuf = 32768; +const size_t rcvbuf = 32768; namespace isc { +namespace dhcp { /// @brief Opens netlink socket and initializes handle structure. /// @@ -121,26 +118,24 @@ void rtnl_send_request(struct rtnl_handle& handle, int family, int type) { } } -/// @brief Appends nlmsg to a list +/// @brief Appends nlmsg to a storage. /// -/// @param n a message to be added -/// @param link_info a list -void rtnl_store_reply(struct nlmsghdr *n, struct nlmsg_list** link_info) +/// @param storage a vector that holds netlink messages +/// @param msg a netlink message to be added +void rtnl_store_reply(NetlinkMessages& storage, const struct nlmsghdr *msg) { - struct nlmsg_list *h; - struct nlmsg_list **lp; - - h = (nlmsg_list*)malloc(n->nlmsg_len+sizeof(void*)); - if (h == NULL) { - isc_throw(Unexpected, "Failed to allocate " << n->nlmsg_len+sizeof(void*) + // we need to make a copy of this message. As those messages are variable size + // it is easier to use malloc + C-style case than do new char[X] and then + // reinterpret_cast<> to struct nlmsghdr. + struct nlmsghdr* copy = (struct nlmsghdr*)malloc(msg->nlmsg_len); + memcpy(copy, msg, msg->nlmsg_len); + if (copy == NULL) { + isc_throw(Unexpected, "Failed to allocate " << msg->nlmsg_len << " bytes."); } - memcpy(&h->h, n, n->nlmsg_len); - h->next = NULL; - - for (lp = link_info; *lp; lp = &(*lp)->next) /* NOTHING */; - *lp = h; + // push_back copies only pointer content, not the pointed object + storage.push_back(copy); } void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) @@ -156,13 +151,13 @@ void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) } } -void ipaddrs_get(IfaceMgr::Iface& iface, struct nlmsg_list *addr_info) { +void ipaddrs_get(IfaceMgr::Iface& iface, NetlinkMessages& addr_info) { uint8_t addr[16]; struct rtattr * rta_tb[IFA_MAX+1]; - for ( ;addr_info ; addr_info = addr_info->next) { - struct nlmsghdr *n = &addr_info->h; - struct ifaddrmsg *ifa = (ifaddrmsg*)NLMSG_DATA(n); + for (NetlinkMessages::const_iterator msg = addr_info.begin(); + msg != addr_info.end(); ++msg) { + struct ifaddrmsg *ifa = (ifaddrmsg*)NLMSG_DATA(*msg); // these are not the addresses you are looking for if ( ifa->ifa_index != iface.getIndex()) { @@ -171,7 +166,7 @@ void ipaddrs_get(IfaceMgr::Iface& iface, struct nlmsg_list *addr_info) { if ( ifa->ifa_family == AF_INET6 ) { memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); + parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), (*msg)->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); if (!rta_tb[IFA_LOCAL]) rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; if (!rta_tb[IFA_ADDRESS]) @@ -186,7 +181,7 @@ void ipaddrs_get(IfaceMgr::Iface& iface, struct nlmsg_list *addr_info) { if ( ifa->ifa_family == AF_INET ) { memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); + parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), (*msg)->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); if (!rta_tb[IFA_LOCAL]) rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; if (!rta_tb[IFA_ADDRESS]) @@ -199,8 +194,7 @@ void ipaddrs_get(IfaceMgr::Iface& iface, struct nlmsg_list *addr_info) { } } - -void rtnl_process_reply(struct rtnl_handle &rth, struct nlmsg_list *&info) { +void rtnl_process_reply(const struct rtnl_handle& rth, NetlinkMessages& info) { struct sockaddr_nl nladdr; struct iovec iov; @@ -214,9 +208,9 @@ void rtnl_process_reply(struct rtnl_handle &rth, struct nlmsg_list *&info) { char buf[rcvbuf]; iov.iov_base = buf; - while (1) { + while (true) { int status; - struct nlmsghdr *h; + struct nlmsghdr* header; iov.iov_len = sizeof(buf); status = recvmsg(rth.fd, &msg, 0); @@ -231,25 +225,25 @@ void rtnl_process_reply(struct rtnl_handle &rth, struct nlmsg_list *&info) { isc_throw(Unexpected, "EOF while reading netlink socket."); } - h = (struct nlmsghdr*)buf; - while (NLMSG_OK(h, status)) { + header = (struct nlmsghdr*)buf; + while (NLMSG_OK(header, status)) { // why we received this anyway? if (nladdr.nl_pid != 0 || - h->nlmsg_pid != rth.local.nl_pid || - h->nlmsg_seq != rth.dump) { - h = NLMSG_NEXT(h, status); + header->nlmsg_pid != rth.local.nl_pid || + header->nlmsg_seq != rth.dump) { + header = NLMSG_NEXT(header, status); continue; } - if (h->nlmsg_type == NLMSG_DONE) { + if (header->nlmsg_type == NLMSG_DONE) { // end of message return; } - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { + if (header->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(header); + if (header->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { // we are really out of luck here. We can't even say what is // wrong as error message is truncated. D'oh. isc_throw(Unexpected, "Netlink reply read failed."); @@ -261,9 +255,9 @@ void rtnl_process_reply(struct rtnl_handle &rth, struct nlmsg_list *&info) { } // store the data - rtnl_store_reply(h, &info); + rtnl_store_reply(info, header); - h = NLMSG_NEXT(h, status); + header = NLMSG_NEXT(header, status); } if (msg.msg_flags & MSG_TRUNC) { isc_throw(Unexpected, "Message received over netlink truncated."); @@ -276,22 +270,20 @@ void rtnl_process_reply(struct rtnl_handle &rth, struct nlmsg_list *&info) { /// @brief releases nlmsg list /// -/// @param head first element of the list to be released -void release_list(struct nlmsg_list *head) { - struct nlmsg_list *tmp; - while (head) { - tmp = head->next; - free(head); - head = tmp; +/// @param messages first element of the list to be released +void release_list(NetlinkMessages& messages) { + // let's free our copies of stored messages + for (NetlinkMessages::iterator msg = messages.begin(); msg != messages.end(); ++msg) { + free(*msg); } + messages.clear(); } void IfaceMgr::detectIfaces() { cout << "Linux: detecting interfaces." << endl; - struct nlmsg_list* link_info = NULL; // link info list - struct nlmsg_list* addr_info = NULL; // address info list - struct nlmsg_list* l = NULL; + NetlinkMessages link_info; // link info + NetlinkMessages addr_info; // address info struct rtnl_handle rth; // required to display information about interface @@ -318,9 +310,10 @@ void IfaceMgr::detectIfaces() { rtnl_process_reply(rth, addr_info); // Now build list with interface names - for (l=link_info; l; l = l->next) { - ifi = (ifinfomsg*)NLMSG_DATA(&l->h); - len = (&l->h)->nlmsg_len; + for (NetlinkMessages::iterator msg = link_info.begin(); msg != link_info.end(); ++msg) { + // for (l=link_info; l; l = l->next) { + ifi = (ifinfomsg*)NLMSG_DATA(*msg); + len = (*msg)->nlmsg_len; len -= NLMSG_LENGTH(sizeof(*ifi)); parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); @@ -375,6 +368,8 @@ void IfaceMgr::Iface::setFlags(uint32_t flags) { flag_broadcast_ = flags & IFF_BROADCAST; } -} +} // end of isc::dhcp namespace + +} // end of isc namespace #endif // if defined(LINUX)