xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink_interface.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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