blob: 0794b1d5e4c559597cb4ec782f6089f84e8a60c6 [file] [log] [blame]
wubf975eac2019-08-19 19:41:01 -07001// 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 teame571f3a2021-03-16 04:43:45 -07008#include <linux/rtnetlink.h>
9
QUICHE team5be974e2020-12-29 18:35:24 -050010#include "quic/platform/api/quic_ip_address.h"
11#include "quic/qbone/platform/ip_range.h"
wubf975eac2019-08-19 19:41:01 -070012
13namespace quic {
14
15constexpr int kHwAddrSize = 6;
16
17class 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.
25class 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 teamb80d7c32020-02-23 23:44:20 -080041 virtual bool GetLinkInfo(const std::string& interface_name,
wubf975eac2019-08-19 19:41:01 -070042 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_