Apache Mesos
internal.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __LINUX_ROUTING_INTERNAL_HPP__
18 #define __LINUX_ROUTING_INTERNAL_HPP__
19 
20 #include <netlink/cache.h>
21 #include <netlink/errno.h>
22 #include <netlink/netlink.h>
23 #include <netlink/socket.h>
24 
25 #include <memory>
26 #include <string>
27 
28 #include <stout/error.hpp>
29 #include <stout/try.hpp>
30 
31 namespace routing {
32 
33 // Customized deallocation functions for netlink objects.
34 template <typename T>
35 void cleanup(T* t);
36 
37 
38 template <>
39 inline void cleanup(struct nl_cache* cache)
40 {
41  nl_cache_free(cache);
42 }
43 
44 
45 template <>
46 inline void cleanup(struct nl_sock* sock)
47 {
48  nl_socket_free(sock);
49 }
50 
51 
52 // A helper class for managing netlink objects (e.g., rtnl_link,
53 // nl_sock, etc.). It manages the life cycle of a netlink object. It
54 // is copyable and assignable, and multiple copies share the same
55 // underlying netlink object. A netlink object specific cleanup
56 // function will be invoked when the last copy of this wrapper is
57 // being deleted (similar to Future<T>). We use this class to simplify
58 // our code, especially for error handling.
59 template <typename T>
60 class Netlink
61 {
62 public:
63  explicit Netlink(T* object) : data(new Data(object)) {}
64 
65  T* get() const { return data->object; }
66 
67 private:
68  struct Data
69  {
70  explicit Data(T* _object) : object(_object) {}
71 
72  ~Data()
73  {
74  if (object != nullptr) {
75  cleanup(object);
76  }
77  }
78 
79  T* object;
80  };
81 
82  std::shared_ptr<Data> data;
83 };
84 
85 
86 // Returns a netlink socket for communicating with the kernel. This
87 // socket is needed for most of the operations. The default protocol
88 // of the netlink socket is NETLINK_ROUTE, but you can optionally
89 // provide a different one.
90 // TODO(chzhcn): Consider renaming 'routing' to 'netlink'.
91 inline Try<Netlink<struct nl_sock>> socket(int protocol = NETLINK_ROUTE)
92 {
93  struct nl_sock* s = nl_socket_alloc();
94  if (s == nullptr) {
95  return Error("Failed to allocate netlink socket");
96  }
97 
99 
100  int error = nl_connect(sock.get(), protocol);
101  if (error != 0) {
102  return Error(
103  "Failed to connect to netlink protocol: " +
104  std::string(nl_geterror(error)));
105  }
106 
107  return sock;
108 }
109 
110 } // namespace routing {
111 
112 #endif // __LINUX_ROUTING_INTERNAL_HPP__
Definition: errorbase.hpp:36
Definition: check.hpp:33
std::string error(const std::string &msg, uint32_t code)
Definition: diagnosis.hpp:30
void cleanup(struct rtnl_cls *cls)
Definition: internal.hpp:64
Try< Netlink< struct nl_sock > > socket(int protocol=NETLINK_ROUTE)
Definition: internal.hpp:91