summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink.h')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink.h136
1 files changed, 136 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink.h b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink.h
new file mode 100644
index 00000000000..45709c7bd8c
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink.h
@@ -0,0 +1,136 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/qbone/platform/ip_range.h"
+#include "quiche/quic/qbone/platform/kernel_interface.h"
+#include "quiche/quic/qbone/platform/netlink_interface.h"
+
+namespace quic {
+
+// A wrapper class to provide convenient methods of manipulating IP address and
+// routing table using netlink (man 7 netlink) socket. More specifically,
+// rtnetlink is used (man 7 rtnetlink).
+//
+// This class is not thread safe, but thread compatible, as long as callers can
+// make sure Send and Recv pairs are executed in sequence for a particular
+// query.
+class Netlink : public NetlinkInterface {
+ public:
+ explicit Netlink(KernelInterface* kernel);
+ ~Netlink() override;
+
+ // Gets the link information for the interface referred by the given
+ // interface_name.
+ //
+ // This is a synchronous communication. That should not be a problem since the
+ // kernel should answer immediately.
+ bool GetLinkInfo(const std::string& interface_name,
+ LinkInfo* link_info) override;
+
+ // Gets the addresses for the given interface referred by the given
+ // interface_index.
+ //
+ // This is a synchronous communication. This should not be a problem since the
+ // kernel should answer immediately.
+ bool GetAddresses(int interface_index, uint8_t unwanted_flags,
+ std::vector<AddressInfo>* addresses,
+ int* num_ipv6_nodad_dadfailed_addresses) override;
+
+ // Performs the given verb that modifies local addresses on the given
+ // interface_index.
+ //
+ // additional_attributes are RTAs (man 7 rtnelink) that will be sent together
+ // with the netlink message. Note that rta_len in each RTA is used to decide
+ // the length of the payload. The caller is responsible for making sure
+ // payload bytes are accessible after the RTA header.
+ bool ChangeLocalAddress(
+ uint32_t interface_index, Verb verb, const QuicIpAddress& address,
+ uint8_t prefix_length, uint8_t ifa_flags, uint8_t ifa_scope,
+ const std::vector<struct rtattr*>& additional_attributes) override;
+
+ // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
+ // which is programmable.
+ //
+ // This is a synchronous communication. This should not be a problem since the
+ // kernel should answer immediately.
+ bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) override;
+
+ // Performs the given Verb on the matching rule in the main routing table
+ // (RT_TABLE_MAIN).
+ //
+ // preferred_source can be !IsInitialized(), in which case it will be omitted.
+ //
+ // For Verb::kRemove, rule matching is done by (destination_subnet, scope,
+ // preferred_source, interface_index). Return true if a matching rule is
+ // found. interface_index can be 0 for wilecard.
+ //
+ // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for
+ // the given destination_subnet already exists, nothing will happen and false
+ // is returned.
+ //
+ // For Verb::kReplace, rule matching is done by destination_subnet. If no
+ // matching rule is found, a new entry will be created.
+ bool ChangeRoute(Netlink::Verb verb, uint32_t table,
+ const IpRange& destination_subnet, uint8_t scope,
+ QuicIpAddress preferred_source,
+ int32_t interface_index) override;
+
+ // Returns the set of all rules in the routing policy database.
+ bool GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) override;
+
+ // Performs the give verb on the matching rule in the routing policy database.
+ // When deleting a rule, the |source_range| may be unspecified, in which case
+ // the lowest priority rule from |table| will be removed. When adding a rule,
+ // the |source_address| must be specified.
+ bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) override;
+
+ // Sends a netlink message to the kernel. iov and iovlen represents an array
+ // of struct iovec to be fed into sendmsg. The caller needs to make sure the
+ // message conform to what's expected by NLMSG_* macros.
+ //
+ // This can be useful if more flexibility is needed than the provided
+ // convenient methods can provide.
+ bool Send(struct iovec* iov, size_t iovlen) override;
+
+ // Receives a netlink message from the kernel.
+ // parser will be called on the caller's stack.
+ //
+ // This can be useful if more flexibility is needed than the provided
+ // convenient methods can provide.
+ // TODO(b/69412655): vectorize this.
+ bool Recv(uint32_t seq, NetlinkParserInterface* parser) override;
+
+ private:
+ // Reset the size of recvbuf_ to size. If size is 0, recvbuf_ will be nullptr.
+ void ResetRecvBuf(size_t size);
+
+ // Opens a netlink socket if not already opened.
+ bool OpenSocket();
+
+ // Closes the opened netlink socket. Noop if no netlink socket is opened.
+ void CloseSocket();
+
+ KernelInterface* kernel_;
+ int socket_fd_ = -1;
+ std::unique_ptr<char[]> recvbuf_ = nullptr;
+ size_t recvbuf_length_ = 0;
+ uint32_t seq_; // next msg sequence number
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_