wub | f975eac | 2019-08-19 19:41:01 -0700 | [diff] [blame] | 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 | |
QUICHE team | e571f3a | 2021-03-16 04:43:45 -0700 | [diff] [blame] | 8 | #include <linux/rtnetlink.h> |
| 9 | |
QUICHE team | 5be974e | 2020-12-29 18:35:24 -0500 | [diff] [blame] | 10 | #include "quic/platform/api/quic_ip_address.h" |
| 11 | #include "quic/qbone/platform/ip_range.h" |
wub | f975eac | 2019-08-19 19:41:01 -0700 | [diff] [blame] | 12 | |
| 13 | namespace quic { |
| 14 | |
| 15 | constexpr int kHwAddrSize = 6; |
| 16 | |
| 17 | class NetlinkParserInterface { |
| 18 | public: |
| 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. |
QUICHE team | b80d7c3 | 2020-02-23 23:44:20 -0800 | [diff] [blame] | 41 | virtual bool GetLinkInfo(const std::string& interface_name, |
wub | f975eac | 2019-08-19 19:41:01 -0700 | [diff] [blame] | 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, |
| 55 | uint8_t unwanted_flags, |
| 56 | std::vector<AddressInfo>* addresses, |
| 57 | int* num_ipv6_nodad_dadfailed_addresses) = 0; |
| 58 | |
| 59 | enum class Verb { |
| 60 | kAdd, |
| 61 | kRemove, |
| 62 | kReplace, |
| 63 | }; |
| 64 | |
| 65 | // Performs the given verb that modifies local addresses on the given |
| 66 | // interface_index. |
| 67 | // |
| 68 | // additional_attributes are RTAs (man 7 rtnelink) that will be sent together |
| 69 | // with the netlink message. Note that rta_len in each RTA is used to decide |
| 70 | // the length of the payload. The caller is responsible for making sure |
| 71 | // payload bytes are accessible after the RTA header. |
| 72 | virtual bool ChangeLocalAddress( |
| 73 | uint32_t interface_index, |
| 74 | Verb verb, |
| 75 | const QuicIpAddress& address, |
| 76 | uint8_t prefix_length, |
| 77 | uint8_t ifa_flags, |
| 78 | uint8_t ifa_scope, |
| 79 | const std::vector<struct rtattr*>& additional_attributes) = 0; |
| 80 | |
| 81 | // Routing rule reported back from GetRouteInfo. |
| 82 | struct RoutingRule { |
| 83 | uint32_t table; |
| 84 | IpRange destination_subnet; |
| 85 | QuicIpAddress preferred_source; |
| 86 | uint8_t scope; |
| 87 | int out_interface; |
| 88 | }; |
| 89 | |
| 90 | struct IpRule { |
| 91 | uint32_t table; |
| 92 | IpRange source_range; |
| 93 | }; |
| 94 | |
| 95 | // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN), |
| 96 | // which is programmable. |
| 97 | virtual bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) = 0; |
| 98 | |
| 99 | // Performs the given Verb on the matching rule in the main routing table |
| 100 | // (RT_TABLE_MAIN). |
| 101 | // |
| 102 | // preferred_source can be !IsInitialized(), in which case it will be omitted. |
| 103 | // |
| 104 | // For Verb::kRemove, rule matching is done by (destination_subnet, scope, |
| 105 | // preferred_source, interface_index). Return true if a matching rule is |
| 106 | // found. interface_index can be 0 for wilecard. |
| 107 | // |
| 108 | // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for |
| 109 | // the given destination_subnet already exists, nothing will happen and false |
| 110 | // is returned. |
| 111 | // |
| 112 | // For Verb::kReplace, rule matching is done by destination_subnet. If no |
| 113 | // matching rule is found, a new entry will be created. |
| 114 | virtual bool ChangeRoute(Verb verb, |
| 115 | uint32_t table, |
| 116 | const IpRange& destination_subnet, |
| 117 | uint8_t scope, |
| 118 | QuicIpAddress preferred_source, |
| 119 | int32_t interface_index) = 0; |
| 120 | |
| 121 | // Returns the set of all rules in the routing policy database. |
| 122 | virtual bool GetRuleInfo(std::vector<IpRule>* ip_rules) = 0; |
| 123 | |
| 124 | // Performs the give verb on the matching rule in the routing policy database. |
| 125 | // When deleting a rule, the |source_range| may be unspecified, in which case |
| 126 | // the lowest priority rule from |table| will be removed. When adding a rule, |
| 127 | // the |source_address| must be specified. |
| 128 | virtual bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) = 0; |
| 129 | |
| 130 | // Sends a netlink message to the kernel. iov and iovlen represents an array |
| 131 | // of struct iovec to be fed into sendmsg. The caller needs to make sure the |
| 132 | // message conform to what's expected by NLMSG_* macros. |
| 133 | // |
| 134 | // This can be useful if more flexibility is needed than the provided |
| 135 | // convenient methods can provide. |
| 136 | virtual bool Send(struct iovec* iov, size_t iovlen) = 0; |
| 137 | |
| 138 | // Receives a netlink message from the kernel. |
| 139 | // parser will be called on the caller's stack. |
| 140 | // |
| 141 | // This can be useful if more flexibility is needed than the provided |
| 142 | // convenient methods can provide. |
| 143 | virtual bool Recv(uint32_t seq, NetlinkParserInterface* parser) = 0; |
| 144 | }; |
| 145 | |
| 146 | } // namespace quic |
| 147 | |
| 148 | #endif // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_ |