1 // Copyright (c) 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_ 6 #define QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_ 7 8 #include <linux/netlink.h> 9 #include <linux/rtnetlink.h> 10 #include <stdint.h> 11 #include <sys/socket.h> 12 #include <sys/uio.h> 13 14 #include <memory> 15 #include <vector> 16 17 #include "quiche/quic/platform/api/quic_logging.h" 18 19 namespace quic { 20 21 // This base class is used to construct an array struct iovec that represents a 22 // rtnetlink message as defined in man 7 rtnet. Padding for message header 23 // alignment to conform NLMSG_* and RTA_* macros is added at the end of each 24 // iovec::iov_base. 25 class RtnetlinkMessage { 26 public: 27 virtual ~RtnetlinkMessage(); 28 29 enum class Operation { 30 NEW, 31 DEL, 32 GET, 33 }; 34 35 // Appends a struct rtattr to the message. nlmsg_len and rta_len is handled 36 // properly. 37 // Override this to perform check on type. 38 virtual void AppendAttribute(uint16_t type, const void* data, 39 uint16_t data_length); 40 41 // Builds the array of iovec that can be fed into sendmsg directly. 42 std::unique_ptr<struct iovec[]> BuildIoVec() const; 43 44 // The size of the array of iovec if BuildIovec is called. 45 size_t IoVecSize() const; 46 47 protected: 48 // Subclass should add their own message header immediately after the 49 // nlmsghdr. Make this private to force the creation of such header. 50 RtnetlinkMessage(uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid, 51 const void* payload_header, size_t payload_header_length); 52 53 // Adjusts nlmsg_len in the header assuming additional_data_length is appended 54 // at the end. 55 void AdjustMessageLength(size_t additional_data_length); 56 57 private: 58 // Convenient function for accessing the nlmsghdr. 59 struct nlmsghdr* MessageHeader(); 60 61 std::vector<struct iovec> message_; 62 }; 63 64 // Message for manipulating link level configuration as defined in man 7 65 // rtnetlink. RTM_NEWLINK, RTM_DELLINK and RTM_GETLINK are supported. 66 class LinkMessage : public RtnetlinkMessage { 67 public: 68 static LinkMessage New(RtnetlinkMessage::Operation request_operation, 69 uint16_t flags, uint32_t seq, uint32_t pid, 70 const struct ifinfomsg* interface_info_header); 71 72 private: 73 using RtnetlinkMessage::RtnetlinkMessage; 74 }; 75 76 // Message for manipulating address level configuration as defined in man 7 77 // rtnetlink. RTM_NEWADDR, RTM_NEWADDR and RTM_GETADDR are supported. 78 class AddressMessage : public RtnetlinkMessage { 79 public: 80 static AddressMessage New(RtnetlinkMessage::Operation request_operation, 81 uint16_t flags, uint32_t seq, uint32_t pid, 82 const struct ifaddrmsg* interface_address_header); 83 84 private: 85 using RtnetlinkMessage::RtnetlinkMessage; 86 }; 87 88 // Message for manipulating routing table as defined in man 7 rtnetlink. 89 // RTM_NEWROUTE, RTM_DELROUTE and RTM_GETROUTE are supported. 90 class RouteMessage : public RtnetlinkMessage { 91 public: 92 static RouteMessage New(RtnetlinkMessage::Operation request_operation, 93 uint16_t flags, uint32_t seq, uint32_t pid, 94 const struct rtmsg* route_message_header); 95 96 private: 97 using RtnetlinkMessage::RtnetlinkMessage; 98 }; 99 100 class RuleMessage : public RtnetlinkMessage { 101 public: 102 static RuleMessage New(RtnetlinkMessage::Operation request_operation, 103 uint16_t flags, uint32_t seq, uint32_t pid, 104 const struct rtmsg* rule_message_header); 105 106 private: 107 using RtnetlinkMessage::RtnetlinkMessage; 108 }; 109 110 } // namespace quic 111 112 #endif // QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_ 113