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:39 UTC
[9/9] git commit: Added API for managing ARP packet filters.
Added API for managing ARP packet filters.
Review: https://reviews.apache.org/r/20296
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/336420c6
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/336420c6
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/336420c6
Branch: refs/heads/master
Commit: 336420c66516d09211ecbebf3310b45517e35577
Parents: 6d068b2
Author: Jie Yu <yu...@gmail.com>
Authored: Sun Apr 13 11:42:11 2014 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Wed May 14 17:38:43 2014 -0700
----------------------------------------------------------------------
src/Makefile.am | 2 +
src/linux/routing/filter/arp.cpp | 164 ++++++++++++++++++++++++++++++++++
src/linux/routing/filter/arp.hpp | 84 +++++++++++++++++
src/tests/routing_tests.cpp | 106 ++++++++++++++++++++++
4 files changed, 356 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/336420c6/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index c18ddf0..ddbd82b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -270,6 +270,7 @@ if WITH_NETWORK_ISOLATOR
libmesos_no_3rdparty_la_SOURCES += \
linux/routing/utils.cpp \
linux/routing/link/link.cpp \
+ linux/routing/filter/arp.cpp \
linux/routing/filter/icmp.cpp \
linux/routing/queueing/handle.cpp \
linux/routing/queueing/ingress.cpp
@@ -278,6 +279,7 @@ if WITH_NETWORK_ISOLATOR
linux/routing/internal.hpp \
linux/routing/utils.hpp \
linux/routing/filter/action.hpp \
+ linux/routing/filter/arp.hpp \
linux/routing/filter/filter.hpp \
linux/routing/filter/icmp.hpp \
linux/routing/filter/internal.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/336420c6/src/linux/routing/filter/arp.cpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/filter/arp.cpp b/src/linux/routing/filter/arp.cpp
new file mode 100644
index 0000000..3f37a83
--- /dev/null
+++ b/src/linux/routing/filter/arp.cpp
@@ -0,0 +1,164 @@
+/**
+ * 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 <linux/if_ether.h>
+
+#include <netlink/errno.h>
+
+#include <netlink/route/tc.h>
+
+#include <netlink/route/cls/basic.h>
+
+#include <stout/error.hpp>
+#include <stout/none.hpp>
+
+#include "linux/routing/internal.hpp"
+
+#include "linux/routing/filter/action.hpp"
+#include "linux/routing/filter/arp.hpp"
+#include "linux/routing/filter/filter.hpp"
+#include "linux/routing/filter/internal.hpp"
+#include "linux/routing/filter/priority.hpp"
+
+#include "linux/routing/queueing/handle.hpp"
+
+using std::string;
+
+namespace routing {
+namespace filter {
+namespace arp {
+
+// The classifier for ARP packet filters contains nothing and is not
+// exposed to the user as we don't care about the content in the ARP
+// packet.
+struct Classifier
+{
+ bool operator == (const Classifier& that) const
+ {
+ return true;
+ }
+};
+
+} // namespace arp {
+
+/////////////////////////////////////////////////
+// Filter specific pack/unpack functions.
+/////////////////////////////////////////////////
+
+namespace internal {
+
+// Encodes the ARP classifier into the libnl filter 'cls'. Each type
+// of classifier needs to implement this function.
+template <>
+Try<Nothing> encode<arp::Classifier>(
+ const Netlink<struct rtnl_cls>& cls,
+ const arp::Classifier& classifier)
+{
+ rtnl_cls_set_protocol(cls.get(), ETH_P_ARP);
+
+ int err = rtnl_tc_set_kind(TC_CAST(cls.get()), "basic");
+ if (err != 0) {
+ return Error(
+ "Failed to set the kind of the classifier: " +
+ string(nl_geterror(err)));
+ }
+
+ return Nothing();
+}
+
+// Decodes the ARP classifier from the libnl filter 'cls'. Each type
+// of classifier needs to implement this function. Returns None if the
+// libnl filter is not an ARP packet filter.
+template <>
+Result<arp::Classifier> decode<arp::Classifier>(
+ const Netlink<struct rtnl_cls>& cls)
+{
+ if (rtnl_cls_get_protocol(cls.get()) == ETH_P_ARP &&
+ rtnl_tc_get_kind(TC_CAST(cls.get())) == string("basic")) {
+ return arp::Classifier();
+ }
+
+ return None();
+}
+
+} // namespace internal {
+
+
+namespace arp {
+
+Try<bool> exists(const string& link, const queueing::Handle& parent)
+{
+ return internal::exists(link, parent, Classifier());
+}
+
+
+Try<bool> create(
+ const string& link,
+ const queueing::Handle& parent,
+ const Option<Priority>& priority,
+ const action::Redirect& redirect)
+{
+ return internal::create(
+ link,
+ Filter<Classifier>(
+ parent,
+ Classifier(),
+ priority,
+ redirect));
+}
+
+
+Try<bool> create(
+ const string& link,
+ const queueing::Handle& parent,
+ const Option<Priority>& priority,
+ const action::Mirror& mirror)
+{
+ return internal::create(
+ link,
+ Filter<Classifier>(
+ parent,
+ Classifier(),
+ priority,
+ mirror));
+}
+
+
+Try<bool> remove(const string& link, const queueing::Handle& parent)
+{
+ return internal::remove(link, parent, Classifier());
+}
+
+
+Try<bool> update(
+ const string& link,
+ const queueing::Handle& parent,
+ const action::Mirror& mirror)
+{
+ return internal::update(
+ link,
+ Filter<Classifier>(
+ parent,
+ Classifier(),
+ None(),
+ mirror));
+}
+
+} // namespace arp {
+} // namespace filter {
+} // namespace routing {
http://git-wip-us.apache.org/repos/asf/mesos/blob/336420c6/src/linux/routing/filter/arp.hpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/filter/arp.hpp b/src/linux/routing/filter/arp.hpp
new file mode 100644
index 0000000..fa0ea6f
--- /dev/null
+++ b/src/linux/routing/filter/arp.hpp
@@ -0,0 +1,84 @@
+/**
+ * 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_FILTER_ARP_HPP__
+#define __LINUX_ROUTING_FILTER_ARP_HPP__
+
+#include <string>
+
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+#include "linux/routing/filter/action.hpp"
+#include "linux/routing/filter/filter.hpp"
+#include "linux/routing/filter/priority.hpp"
+
+#include "linux/routing/queueing/handle.hpp"
+
+namespace routing {
+namespace filter {
+namespace arp {
+
+// Returns true if an ARP packet filter attached to the given parent
+// exists on the link.
+Try<bool> exists(const std::string& link, const queueing::Handle& parent);
+
+
+// Creates an ARP packet filter attached to the given parent on the
+// link which will redirect all ARP packets to the target link.
+// Returns false if an ARP packet filter attached to the given parent
+// already exists on the link. The user can choose to specify an
+// optional priority for the filter.
+Try<bool> create(
+ const std::string& link,
+ const queueing::Handle& parent,
+ const Option<Priority>& priority,
+ const action::Redirect& redirect);
+
+
+// Creates an ARP packet filter attached to the given parent on the
+// link which will mirror all ARP packets to a set of links (specified
+// in the mirror action). Returns false if an ARP packet filter
+// attached to the given parent already exists on the link. The user
+// can choose to specify an optional priority for the filter.
+Try<bool> create(
+ const std::string& link,
+ const queueing::Handle& parent,
+ const Option<Priority>& priority,
+ const action::Mirror& mirror);
+
+
+// Removes the ARP packet filter attached to the parent from the link.
+// Returns false if no ARP packet filter attached to the given parent
+// is found on the link.
+Try<bool> remove(const std::string& link, const queueing::Handle& parent);
+
+
+// Updates the action of the APR packet filter attached to the given
+// parent on the link. Returns false if no ARP packet filter attached
+// to the parent is found on the link.
+Try<bool> update(
+ const std::string& link,
+ const queueing::Handle& parent,
+ const action::Mirror& mirror);
+
+} // namespace arp {
+} // namespace filter {
+} // namespace routing {
+
+#endif // __LINUX_ROUTING_FILTER_ARP_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/336420c6/src/tests/routing_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/routing_tests.cpp b/src/tests/routing_tests.cpp
index de6d9e3..cc3d6da 100644
--- a/src/tests/routing_tests.cpp
+++ b/src/tests/routing_tests.cpp
@@ -33,6 +33,7 @@
#include "linux/routing/utils.hpp"
+#include "linux/routing/filter/arp.hpp"
#include "linux/routing/filter/icmp.hpp"
#include "linux/routing/link/link.hpp"
@@ -292,6 +293,111 @@ TEST_F(RoutingVethTest, ROOT_LinkMTU)
}
+TEST_F(RoutingVethTest, ROOT_ARPFilterCreate)
+{
+ ASSERT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));
+
+ EXPECT_SOME_TRUE(link::exists(TEST_VETH_LINK));
+ EXPECT_SOME_TRUE(link::exists(TEST_PEER_LINK));
+
+ ASSERT_SOME_TRUE(ingress::create(TEST_VETH_LINK));
+
+ EXPECT_SOME_TRUE(arp::create(
+ TEST_VETH_LINK,
+ ingress::HANDLE,
+ None(),
+ action::Redirect(TEST_PEER_LINK)));
+
+ EXPECT_SOME_TRUE(arp::exists(TEST_VETH_LINK, ingress::HANDLE));
+}
+
+
+TEST_F(RoutingVethTest, ROOT_ARPFilterCreateDuplicated)
+{
+ ASSERT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));
+
+ EXPECT_SOME_TRUE(link::exists(TEST_VETH_LINK));
+ EXPECT_SOME_TRUE(link::exists(TEST_PEER_LINK));
+
+ ASSERT_SOME_TRUE(ingress::create(TEST_VETH_LINK));
+
+ set<string> links;
+ links.insert(TEST_PEER_LINK);
+
+ EXPECT_SOME_TRUE(arp::create(
+ TEST_VETH_LINK,
+ ingress::HANDLE,
+ None(),
+ action::Mirror(links)));
+
+ EXPECT_SOME_TRUE(arp::exists(TEST_VETH_LINK, ingress::HANDLE));
+
+ EXPECT_SOME_FALSE(arp::create(
+ TEST_VETH_LINK,
+ ingress::HANDLE,
+ None(),
+ action::Redirect(TEST_PEER_LINK)));
+}
+
+
+TEST_F(RoutingVethTest, ROOT_ARPFilterRemove)
+{
+ ASSERT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));
+
+ EXPECT_SOME_TRUE(link::exists(TEST_VETH_LINK));
+ EXPECT_SOME_TRUE(link::exists(TEST_PEER_LINK));
+
+ ASSERT_SOME_TRUE(ingress::create(TEST_VETH_LINK));
+
+ set<string> links;
+ links.insert(TEST_PEER_LINK);
+
+ EXPECT_SOME_TRUE(arp::create(
+ TEST_VETH_LINK,
+ ingress::HANDLE,
+ None(),
+ action::Mirror(links)));
+
+ EXPECT_SOME_TRUE(arp::exists(TEST_VETH_LINK, ingress::HANDLE));
+ EXPECT_SOME_TRUE(arp::remove(TEST_VETH_LINK, ingress::HANDLE));
+ EXPECT_SOME_FALSE(arp::exists(TEST_VETH_LINK, ingress::HANDLE));
+}
+
+
+TEST_F(RoutingVethTest, ROOT_ARPFilterUpdate)
+{
+ ASSERT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));
+
+ EXPECT_SOME_TRUE(link::exists(TEST_VETH_LINK));
+ EXPECT_SOME_TRUE(link::exists(TEST_PEER_LINK));
+
+ ASSERT_SOME_TRUE(ingress::create(TEST_VETH_LINK));
+
+ set<string> links;
+ links.insert(TEST_PEER_LINK);
+
+ EXPECT_SOME_FALSE(arp::update(
+ TEST_VETH_LINK,
+ ingress::HANDLE,
+ action::Mirror(links)));
+
+ EXPECT_SOME_TRUE(arp::create(
+ TEST_VETH_LINK,
+ ingress::HANDLE,
+ None(),
+ action::Redirect(TEST_PEER_LINK)));
+
+ EXPECT_SOME_TRUE(arp::exists(TEST_VETH_LINK, ingress::HANDLE));
+
+ EXPECT_SOME_TRUE(arp::update(
+ TEST_VETH_LINK,
+ ingress::HANDLE,
+ action::Mirror(links)));
+
+ EXPECT_SOME_TRUE(arp::exists(TEST_VETH_LINK, ingress::HANDLE));
+}
+
+
TEST_F(RoutingVethTest, ROOT_ICMPFilterCreate)
{
ASSERT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));