| // Copyright (c) 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_ |
| #define QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_ |
| |
| #include <linux/netlink.h> |
| #include <linux/rtnetlink.h> |
| #include <stdint.h> |
| #include <sys/socket.h> |
| #include <sys/uio.h> |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "quiche/quic/platform/api/quic_logging.h" |
| |
| namespace quic { |
| |
| // This base class is used to construct an array struct iovec that represents a |
| // rtnetlink message as defined in man 7 rtnet. Padding for message header |
| // alignment to conform NLMSG_* and RTA_* macros is added at the end of each |
| // iovec::iov_base. |
| class RtnetlinkMessage { |
| public: |
| virtual ~RtnetlinkMessage(); |
| |
| enum class Operation { |
| NEW, |
| DEL, |
| GET, |
| }; |
| |
| // Appends a struct rtattr to the message. nlmsg_len and rta_len is handled |
| // properly. |
| // Override this to perform check on type. |
| virtual void AppendAttribute(uint16_t type, const void* data, |
| uint16_t data_length); |
| |
| // Builds the array of iovec that can be fed into sendmsg directly. |
| std::unique_ptr<struct iovec[]> BuildIoVec() const; |
| |
| // The size of the array of iovec if BuildIovec is called. |
| size_t IoVecSize() const; |
| |
| protected: |
| // Subclass should add their own message header immediately after the |
| // nlmsghdr. Make this private to force the creation of such header. |
| RtnetlinkMessage(uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid, |
| const void* payload_header, size_t payload_header_length); |
| |
| // Adjusts nlmsg_len in the header assuming additional_data_length is appended |
| // at the end. |
| void AdjustMessageLength(size_t additional_data_length); |
| |
| private: |
| // Convenient function for accessing the nlmsghdr. |
| struct nlmsghdr* MessageHeader(); |
| |
| std::vector<struct iovec> message_; |
| }; |
| |
| // Message for manipulating link level configuration as defined in man 7 |
| // rtnetlink. RTM_NEWLINK, RTM_DELLINK and RTM_GETLINK are supported. |
| class LinkMessage : public RtnetlinkMessage { |
| public: |
| static LinkMessage New(RtnetlinkMessage::Operation request_operation, |
| uint16_t flags, uint32_t seq, uint32_t pid, |
| const struct ifinfomsg* interface_info_header); |
| |
| private: |
| using RtnetlinkMessage::RtnetlinkMessage; |
| }; |
| |
| // Message for manipulating address level configuration as defined in man 7 |
| // rtnetlink. RTM_NEWADDR, RTM_NEWADDR and RTM_GETADDR are supported. |
| class AddressMessage : public RtnetlinkMessage { |
| public: |
| static AddressMessage New(RtnetlinkMessage::Operation request_operation, |
| uint16_t flags, uint32_t seq, uint32_t pid, |
| const struct ifaddrmsg* interface_address_header); |
| |
| private: |
| using RtnetlinkMessage::RtnetlinkMessage; |
| }; |
| |
| // Message for manipulating routing table as defined in man 7 rtnetlink. |
| // RTM_NEWROUTE, RTM_DELROUTE and RTM_GETROUTE are supported. |
| class RouteMessage : public RtnetlinkMessage { |
| public: |
| static RouteMessage New(RtnetlinkMessage::Operation request_operation, |
| uint16_t flags, uint32_t seq, uint32_t pid, |
| const struct rtmsg* route_message_header); |
| |
| private: |
| using RtnetlinkMessage::RtnetlinkMessage; |
| }; |
| |
| class RuleMessage : public RtnetlinkMessage { |
| public: |
| static RuleMessage New(RtnetlinkMessage::Operation request_operation, |
| uint16_t flags, uint32_t seq, uint32_t pid, |
| const struct rtmsg* rule_message_header); |
| |
| private: |
| using RtnetlinkMessage::RtnetlinkMessage; |
| }; |
| |
| } // namespace quic |
| |
| #endif // QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_ |