blob: 0794b1d5e4c559597cb4ec782f6089f84e8a60c6 [file] [log] [blame]
// 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.
#include <linux/rtnetlink.h>
#include "quic/platform/api/quic_ip_address.h"
#include "quic/qbone/platform/ip_range.h"
namespace quic {
constexpr int kHwAddrSize = 6;
class NetlinkParserInterface {
virtual ~NetlinkParserInterface() {}
virtual void Run(struct nlmsghdr* netlink_message) = 0;
// An interface providing convenience methods for manipulating IP address and
// routing table using netlink (man 7 netlink) socket.
class NetlinkInterface {
virtual ~NetlinkInterface() = default;
// Link information returned from GetLinkInfo.
struct LinkInfo {
int index;
uint8_t type;
uint8_t hardware_address[kHwAddrSize];
uint8_t broadcast_address[kHwAddrSize];
size_t hardware_address_length; // 0 if no hardware address found
size_t broadcast_address_length; // 0 if no broadcast address found
// Gets the link information for the interface referred by the given
// interface_name.
virtual bool GetLinkInfo(const std::string& interface_name,
LinkInfo* link_info) = 0;
// Address information reported back from GetAddresses.
struct AddressInfo {
QuicIpAddress local_address;
QuicIpAddress interface_address;
uint8_t prefix_length = 0;
uint8_t scope = 0;
// Gets the addresses for the given interface referred by the given
// interface_index.
virtual bool GetAddresses(int interface_index,
uint8_t unwanted_flags,
std::vector<AddressInfo>* addresses,
int* num_ipv6_nodad_dadfailed_addresses) = 0;
enum class Verb {
// 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.
virtual 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) = 0;
// Routing rule reported back from GetRouteInfo.
struct RoutingRule {
uint32_t table;
IpRange destination_subnet;
QuicIpAddress preferred_source;
uint8_t scope;
int out_interface;
struct IpRule {
uint32_t table;
IpRange source_range;
// Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
// which is programmable.
virtual bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) = 0;
// Performs the given Verb on the matching rule in the main routing table
// 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.
virtual bool ChangeRoute(Verb verb,
uint32_t table,
const IpRange& destination_subnet,
uint8_t scope,
QuicIpAddress preferred_source,
int32_t interface_index) = 0;
// Returns the set of all rules in the routing policy database.
virtual bool GetRuleInfo(std::vector<IpRule>* ip_rules) = 0;
// 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.
virtual bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) = 0;
// 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.
virtual bool Send(struct iovec* iov, size_t iovlen) = 0;
// 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.
virtual bool Recv(uint32_t seq, NetlinkParserInterface* parser) = 0;
} // namespace quic