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_NETLINK_INTERFACE_H_ 6 #define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_ 7 8 #include <linux/rtnetlink.h> 9 10 #include "quiche/quic/platform/api/quic_ip_address.h" 11 #include "quiche/quic/qbone/platform/ip_range.h" 12 13 namespace quic { 14 15 constexpr int kHwAddrSize = 6; 16 17 class NetlinkParserInterface { 18 public: ~NetlinkParserInterface()19 virtual ~NetlinkParserInterface() {} 20 virtual void Run(struct nlmsghdr* netlink_message) = 0; 21 }; 22 23 // An interface providing convenience methods for manipulating IP address and 24 // routing table using netlink (man 7 netlink) socket. 25 class NetlinkInterface { 26 public: 27 virtual ~NetlinkInterface() = default; 28 29 // Link information returned from GetLinkInfo. 30 struct LinkInfo { 31 int index; 32 uint8_t type; 33 uint8_t hardware_address[kHwAddrSize]; 34 uint8_t broadcast_address[kHwAddrSize]; 35 size_t hardware_address_length; // 0 if no hardware address found 36 size_t broadcast_address_length; // 0 if no broadcast address found 37 }; 38 39 // Gets the link information for the interface referred by the given 40 // interface_name. 41 virtual bool GetLinkInfo(const std::string& interface_name, 42 LinkInfo* link_info) = 0; 43 44 // Address information reported back from GetAddresses. 45 struct AddressInfo { 46 QuicIpAddress local_address; 47 QuicIpAddress interface_address; 48 uint8_t prefix_length = 0; 49 uint8_t scope = 0; 50 }; 51 52 // Gets the addresses for the given interface referred by the given 53 // interface_index. 54 virtual bool GetAddresses(int interface_index, uint8_t unwanted_flags, 55 std::vector<AddressInfo>* addresses, 56 int* num_ipv6_nodad_dadfailed_addresses) = 0; 57 58 enum class Verb { 59 kAdd, 60 kRemove, 61 kReplace, 62 }; 63 64 // Performs the given verb that modifies local addresses on the given 65 // interface_index. 66 // 67 // additional_attributes are RTAs (man 7 rtnelink) that will be sent together 68 // with the netlink message. Note that rta_len in each RTA is used to decide 69 // the length of the payload. The caller is responsible for making sure 70 // payload bytes are accessible after the RTA header. 71 virtual bool ChangeLocalAddress( 72 uint32_t interface_index, Verb verb, const QuicIpAddress& address, 73 uint8_t prefix_length, uint8_t ifa_flags, uint8_t ifa_scope, 74 const std::vector<struct rtattr*>& additional_attributes) = 0; 75 76 static constexpr uint32_t kUnspecifiedInitCwnd = 0; 77 78 // Routing rule reported back from GetRouteInfo. 79 struct RoutingRule { 80 uint32_t table; 81 IpRange destination_subnet; 82 QuicIpAddress preferred_source; 83 uint8_t scope; 84 int out_interface; 85 uint32_t init_cwnd; // kUnspecifiedInitCwnd if unspecified 86 }; 87 88 struct IpRule { 89 uint32_t table; 90 IpRange source_range; 91 }; 92 93 // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN), 94 // which is programmable. 95 virtual bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) = 0; 96 97 // Performs the given Verb on the matching rule in the main routing table 98 // (RT_TABLE_MAIN). 99 // 100 // preferred_source can be !IsInitialized(), in which case it will be omitted. 101 // 102 // For Verb::kRemove, rule matching is done by (destination_subnet, scope, 103 // preferred_source, interface_index). Return true if a matching rule is 104 // found. interface_index can be 0 for wilecard. 105 // 106 // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for 107 // the given destination_subnet already exists, nothing will happen and false 108 // is returned. 109 // 110 // For Verb::kReplace, rule matching is done by destination_subnet. If no 111 // matching rule is found, a new entry will be created. 112 virtual bool ChangeRoute(Verb verb, uint32_t table, 113 const IpRange& destination_subnet, uint8_t scope, 114 QuicIpAddress preferred_source, 115 int32_t interface_index, uint32_t init_cwnd) = 0; 116 117 // Returns the set of all rules in the routing policy database. 118 virtual bool GetRuleInfo(std::vector<IpRule>* ip_rules) = 0; 119 120 // Performs the give verb on the matching rule in the routing policy database. 121 // When deleting a rule, the |source_range| may be unspecified, in which case 122 // the lowest priority rule from |table| will be removed. When adding a rule, 123 // the |source_address| must be specified. 124 virtual bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) = 0; 125 126 // Sends a netlink message to the kernel. iov and iovlen represents an array 127 // of struct iovec to be fed into sendmsg. The caller needs to make sure the 128 // message conform to what's expected by NLMSG_* macros. 129 // 130 // This can be useful if more flexibility is needed than the provided 131 // convenient methods can provide. 132 virtual bool Send(struct iovec* iov, size_t iovlen) = 0; 133 134 // Receives a netlink message from the kernel. 135 // parser will be called on the caller's stack. 136 // 137 // This can be useful if more flexibility is needed than the provided 138 // convenient methods can provide. 139 virtual bool Recv(uint32_t seq, NetlinkParserInterface* parser) = 0; 140 }; 141 142 } // namespace quic 143 144 #endif // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_ 145