You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2014/05/15 03:21:38 UTC
[8/9] git commit: Added API for getting the default gateway.
Added API for getting the default gateway.
Review: https://reviews.apache.org/r/20347
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/19f643aa
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/19f643aa
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/19f643aa
Branch: refs/heads/master
Commit: 19f643aa5b84f3542cd92b0d84bef543c55b9b52
Parents: d6bcfa9
Author: Jie Yu <yu...@gmail.com>
Authored: Mon Apr 14 18:23:45 2014 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Wed May 14 17:38:43 2014 -0700
----------------------------------------------------------------------
src/Makefile.am | 2 +
src/linux/routing/route.cpp | 136 +++++++++++++++++++++++++++++++++++++++
src/linux/routing/route.hpp | 65 +++++++++++++++++++
src/tests/routing_tests.cpp | 11 ++++
4 files changed, 214 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/19f643aa/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index ce97f1b..ae576c5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -268,6 +268,7 @@ endif
if WITH_NETWORK_ISOLATOR
libmesos_no_3rdparty_la_SOURCES += \
+ linux/routing/route.cpp \
linux/routing/utils.cpp \
linux/routing/link/link.cpp \
linux/routing/filter/arp.cpp \
@@ -278,6 +279,7 @@ if WITH_NETWORK_ISOLATOR
libmesos_no_3rdparty_la_SOURCES += \
linux/routing/internal.hpp \
+ linux/routing/route.hpp \
linux/routing/utils.hpp \
linux/routing/filter/action.hpp \
linux/routing/filter/arp.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/19f643aa/src/linux/routing/route.cpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/route.cpp b/src/linux/routing/route.cpp
new file mode 100644
index 0000000..6e3ec0f
--- /dev/null
+++ b/src/linux/routing/route.cpp
@@ -0,0 +1,136 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#include <linux/rtnetlink.h>
+
+#include <netinet/in.h>
+
+#include <netlink/addr.h>
+#include <netlink/cache.h>
+#include <netlink/errno.h>
+#include <netlink/object.h>
+#include <netlink/socket.h>
+
+#include <netlink/route/route.h>
+
+#include <glog/logging.h>
+
+#include <stout/error.hpp>
+#include <stout/foreach.hpp>
+#include <stout/none.hpp>
+#include <stout/stringify.hpp>
+
+#include "linux/routing/internal.hpp"
+#include "linux/routing/route.hpp"
+
+#include "linux/routing/link/link.hpp"
+
+using std::string;
+using std::vector;
+
+namespace routing {
+namespace route {
+
+Try<vector<Rule> > table()
+{
+ Try<Netlink<struct nl_sock> > sock = routing::socket();
+ if (sock.isError()) {
+ return Error(sock.error());
+ }
+
+ // Dump all the routes (for IPv4) from kernel.
+ struct nl_cache* c = NULL;
+ int err = rtnl_route_alloc_cache(sock.get().get(), AF_INET, 0, &c);
+ if (err != 0) {
+ return Error(nl_geterror(err));
+ }
+
+ Netlink<struct nl_cache> cache(c);
+
+ vector<Rule> results;
+
+ // Scan the routes and look for entries in the main routing table.
+ for (struct nl_object* o = nl_cache_get_first(cache.get());
+ o != NULL; o = nl_cache_get_next(o)) {
+ struct rtnl_route* route = (struct rtnl_route*) o;
+
+ // TODO(jieyu): Currently, we assume each route in the routing
+ // table has only one hop (which is true in most environments).
+ if (rtnl_route_get_table(route) == RT_TABLE_MAIN &&
+ rtnl_route_get_nnexthops(route) == 1) {
+ CHECK_EQ(AF_INET, rtnl_route_get_family(route));
+
+ // Get the destination IP if exists.
+ Option<net::IP> destination;
+ struct nl_addr* dst = rtnl_route_get_dst(route);
+ if (dst != NULL && nl_addr_get_len(dst) != 0) {
+ struct in_addr* addr = (struct in_addr*) nl_addr_get_binary_addr(dst);
+
+ // Calculate the netmask based on the prefix length.
+ CHECK_GE(32u, nl_addr_get_prefixlen(dst));
+ uint32_t netmask = 0xffffffff << (32 - nl_addr_get_prefixlen(dst));
+
+ destination = net::IP(ntohl(addr->s_addr), netmask);
+ }
+
+ // Get the default gateway if exists.
+ Option<net::IP> gateway;
+ struct rtnl_nexthop* hop = rtnl_route_nexthop_n(route, 0);
+ struct nl_addr* gw = rtnl_route_nh_get_gateway(CHECK_NOTNULL(hop));
+ if (gw != NULL && nl_addr_get_len(gw) != 0) {
+ struct in_addr* addr = (struct in_addr*) nl_addr_get_binary_addr(gw);
+ gateway = net::IP(ntohl(addr->s_addr));
+ }
+
+ // Get the destination link.
+ int index = rtnl_route_nh_get_ifindex(hop);
+ Result<string> link = link::name(index);
+ if (link.isError()) {
+ return Error("Failed to get the link name: " + link.error());
+ } else if (link.isNone()) {
+ return Error("Link of index " + stringify(index) + " is not found");
+ }
+
+ results.push_back(Rule(destination, gateway, link.get()));
+ }
+ }
+
+ return results;
+}
+
+
+Result<net::IP> defaultGateway()
+{
+ Try<vector<Rule> > rules = table();
+ if (rules.isError()) {
+ return Error("Failed to get the routing table: " + rules.error());
+ }
+
+ foreach (const Rule& rule, rules.get()) {
+ if (rule.destination().isNone() && rule.gateway().isSome()) {
+ return rule.gateway().get();
+ }
+ }
+
+ return None();
+}
+
+} // namespace route
+} // namespace routing
http://git-wip-us.apache.org/repos/asf/mesos/blob/19f643aa/src/linux/routing/route.hpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/route.hpp b/src/linux/routing/route.hpp
new file mode 100644
index 0000000..435b981
--- /dev/null
+++ b/src/linux/routing/route.hpp
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LINUX_ROUTING_ROUTE_HPP__
+#define __LINUX_ROUTING_ROUTE_HPP__
+
+#include <string>
+#include <vector>
+
+#include <stout/net.hpp>
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+namespace routing {
+namespace route {
+
+// Represents a rule in the routing table (for IPv4).
+class Rule
+{
+public:
+ Rule(const Option<net::IP>& _destination,
+ const Option<net::IP>& _gateway,
+ const std::string& _link)
+ : destination_(_destination),
+ gateway_(_gateway),
+ link_(_link) {}
+
+ const Option<net::IP>& destination() const { return destination_; }
+ const Option<net::IP>& gateway() const { return gateway_; }
+ const std::string& link() const { return link_; }
+
+private:
+ Option<net::IP> destination_;
+ Option<net::IP> gateway_;
+ std::string link_;
+};
+
+
+// Returns the main routing table of this host.
+Try<std::vector<Rule> > table();
+
+
+// Returns the default gateway of this host.
+Result<net::IP> defaultGateway();
+
+} // namespace route
+} // namespace routing
+
+#endif // __LINUX_ROUTING_ROUTE_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/19f643aa/src/tests/routing_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/routing_tests.cpp b/src/tests/routing_tests.cpp
index 5650fca..aca88dc 100644
--- a/src/tests/routing_tests.cpp
+++ b/src/tests/routing_tests.cpp
@@ -31,6 +31,7 @@
#include <stout/hashmap.hpp>
#include <stout/net.hpp>
+#include "linux/routing/route.hpp"
#include "linux/routing/utils.hpp"
#include "linux/routing/filter/arp.hpp"
@@ -128,6 +129,16 @@ TEST_F(RoutingTest, PortRange)
}
+TEST_F(RoutingTest, RouteTable)
+{
+ Try<vector<route::Rule> > table = route::table();
+ EXPECT_SOME(table);
+
+ Result<net::IP> gateway = route::defaultGateway();
+ EXPECT_FALSE(gateway.isError());
+}
+
+
TEST_F(RoutingTest, LinkIndex)
{
Try<set<string> > links = net::links();