blob: e67da1bcaa2ab7ee51dcf7d431f85aff5f8f6a5b [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.
#ifndef QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
#define QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <memory>
#include <vector>
#include "quic/platform/api/quic_logging.h"
namespace quic {
// This base class is used to construct an array struct iovec that represents a
// rtnetlink message as defined in man 7 rtnet. Padding for message header
// alignment to conform NLMSG_* and RTA_* macros is added at the end of each
// iovec::iov_base.
class RtnetlinkMessage {
public:
virtual ~RtnetlinkMessage();
enum class Operation {
NEW,
DEL,
GET,
};
// Appends a struct rtattr to the message. nlmsg_len and rta_len is handled
// properly.
// Override this to perform check on type.
virtual void AppendAttribute(uint16_t type,
const void* data,
uint16_t data_length);
// Builds the array of iovec that can be fed into sendmsg directly.
std::unique_ptr<struct iovec[]> BuildIoVec() const;
// The size of the array of iovec if BuildIovec is called.
size_t IoVecSize() const;
protected:
// Subclass should add their own message header immediately after the
// nlmsghdr. Make this private to force the creation of such header.
RtnetlinkMessage(uint16_t type,
uint16_t flags,
uint32_t seq,
uint32_t pid,
const void* payload_header,
size_t payload_header_length);
// Adjusts nlmsg_len in the header assuming additional_data_length is appended
// at the end.
void AdjustMessageLength(size_t additional_data_length);
private:
// Convenient function for accessing the nlmsghdr.
struct nlmsghdr* MessageHeader();
std::vector<struct iovec> message_;
};
// Message for manipulating link level configuration as defined in man 7
// rtnetlink. RTM_NEWLINK, RTM_DELLINK and RTM_GETLINK are supported.
class LinkMessage : public RtnetlinkMessage {
public:
static LinkMessage New(RtnetlinkMessage::Operation request_operation,
uint16_t flags,
uint32_t seq,
uint32_t pid,
const struct ifinfomsg* interface_info_header);
private:
using RtnetlinkMessage::RtnetlinkMessage;
};
// Message for manipulating address level configuration as defined in man 7
// rtnetlink. RTM_NEWADDR, RTM_NEWADDR and RTM_GETADDR are supported.
class AddressMessage : public RtnetlinkMessage {
public:
static AddressMessage New(RtnetlinkMessage::Operation request_operation,
uint16_t flags,
uint32_t seq,
uint32_t pid,
const struct ifaddrmsg* interface_address_header);
private:
using RtnetlinkMessage::RtnetlinkMessage;
};
// Message for manipulating routing table as defined in man 7 rtnetlink.
// RTM_NEWROUTE, RTM_DELROUTE and RTM_GETROUTE are supported.
class RouteMessage : public RtnetlinkMessage {
public:
static RouteMessage New(RtnetlinkMessage::Operation request_operation,
uint16_t flags,
uint32_t seq,
uint32_t pid,
const struct rtmsg* route_message_header);
private:
using RtnetlinkMessage::RtnetlinkMessage;
};
class RuleMessage : public RtnetlinkMessage {
public:
static RuleMessage New(RtnetlinkMessage::Operation request_operation,
uint16_t flags,
uint32_t seq,
uint32_t pid,
const struct rtmsg* rule_message_header);
private:
using RtnetlinkMessage::RtnetlinkMessage;
};
} // namespace quic
#endif // QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_