summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/qbone/platform/rtnetlink_message.h
blob: f36cd4c505f7998a4917ec6778ae65524d66574f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// 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 "net/third_party/quiche/src/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_