netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC net-next 0/6] net: Identifier Locator Addressing
@ 2015-06-03 19:58 Tom Herbert
  2015-06-03 19:58 ` [RFC net-next 1/6] net: Checksum functions to replace 8 bytes at a time Tom Herbert
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Tom Herbert @ 2015-06-03 19:58 UTC (permalink / raw)
  To: davem, agartrell, maheshb, tgraf, netdev

This patch set provides rudimentary support for Identifier Locator
Addresssing or ILA. The basic concept of ILA is that we split and IPv6
in to a 64 bit locator and 64 bit identifier. The identifier is the
identity of an entity in communication ("who") and the locator
expresses a the location of the entity ("where"). Applications
use externally visible address that contains the identifier.
When a packet is actually sent, a translation is done that
overwrites the first 64 bits of the address with a locator.
The packet can the be forwarded over the network to the host where
the addressed entity is located. At the receiver, the reverse
transation is done so the that the application sees the original,
untranslated address. Presumably an external control plane will
provide identfier->locator mapping.

The data path for ILA is a simple NAT translation that only operates
on the upper 64 bits of a destination address in IPv6 packets. The
basic process is:

   1) Lookup 64 bit identifier (lower 64 bits of destination) in a table
   2) If a match is found
      a) Overwrite locator (upper 64 bits of destination) with
         new locator
      b) Adjust any checksum that has destination address included in
         pseudo header
   3) Send or receive packet

ILA is a means to implement tunnels or network virtualization without
encapsulation. Since there is no encapsulation involved, we assume that
statelss support in the network for IPv6 (e.g. RSS, ECMP, TSO, etc.)
just works. Also, since we're minimally changing the packet many of
the worries about encapsulation (MTU, checksum, fragmentation) are
not relevant. The downside is that, ILA is not extensible like other
encapsulations (GUE for instance) so it might not be appropriate for
all use cases. Also, this only makes sense to do in IPv6!

A key aspect of ILA is performance. The intent is that ILA would be
used in data centers in virtualizing tasks or jobs. In the fullest
incarnation all intra data center communications might be targeted to
virtual ILA addresses. This is basically adding a new virtualization
capability to the existing services in a datacenter, so there is a
strong expectation is that this does not degrade performance
for applications.

Performance seems to be dependent on how ILA is hooked into kernel.
This patch set includes IPtables, hacked up IPvlan, and a "special
route" that calls directly into ILA module from where PRE and
POST routing NF_HOOKs are. The best of these performance-wise
is the special hook which seems to be ~2-3% loss of performance
compared to native non-ILA. The other two are ~5% loss. My hope is
to get a solution with <1% performance loss.

Performance testing:

Performing netperf TCP_RR with 200 clients:

Non-ILA baselin
  83.95% CPU utilization
  1729209.7 99.3 178.6 363.9

Special route
  84.63% CPU utilization
  1685847.2 tps				-2.5%
  102/182/367 50/90/99% latencies

IPVL hook
  84.78% CPU utilization
  1638595.9				-5.5%
  106/187/374 50/90/99% latencies

IPtables
  85.10% CPU utilization
  1634015.5 tps				-5.8%
  105/188/380 50/90/99% latencies

References:

Slides from netfconf:
http://vger.kernel.org/netconf2015Herbert-ILA.pdf

Slides from presentation at IETF:
https://www.ietf.org/proceedings/92/slides/slides-92-nvo3-1.pdf

I-D:
https://tools.ietf.org/html/draft-herbert-nvo3-ila-00

Also, ILA is very much liek ILNP data plane.


Tom Herbert (6):
  net: Checksum functions to replace 8 bytes at a time
  net: Identfier Locator Addressing module
  net: Special routing hook
  net: ILA use special route hook
  net: ILA iptables target
  ipvlan: Call ILA in incoming and outgoing receive paths

 drivers/net/ipvlan/ipvlan.h      |   1 +
 drivers/net/ipvlan/ipvlan_core.c |  27 ++-
 drivers/net/ipvlan/ipvlan_main.c |   4 +
 include/net/checksum.h           |   3 +
 include/net/ila.h                |   7 +
 include/net/ip6_route.h          |  22 ++
 net/core/utils.c                 |  19 ++
 net/ipv6/Kconfig                 |   8 +
 net/ipv6/Makefile                |   1 +
 net/ipv6/ila.c                   | 509 +++++++++++++++++++++++++++++++++++++++
 net/ipv6/ip6_input.c             |   3 +
 net/ipv6/ip6_output.c            |  24 +-
 net/ipv6/route.c                 |  51 ++++
 net/ipv6/xfrm6_input.c           |   4 +
 net/netfilter/Kconfig            |  11 +
 net/netfilter/Makefile           |   1 +
 net/netfilter/xt_ILA.c           |  82 +++++++
 17 files changed, 767 insertions(+), 10 deletions(-)
 create mode 100644 include/net/ila.h
 create mode 100644 net/ipv6/ila.c
 create mode 100644 net/netfilter/xt_ILA.c

-- 
1.8.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC net-next 1/6] net: Checksum functions to replace 8 bytes at a time
  2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
@ 2015-06-03 19:58 ` Tom Herbert
  2015-06-03 19:58 ` [RFC net-next 2/6] net: Identfier Locator Addressing module Tom Herbert
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Tom Herbert @ 2015-06-03 19:58 UTC (permalink / raw)
  To: davem, agartrell, maheshb, tgraf, netdev

These are convenience functions for update a checksum in ILA where we
are overwriting the locator (first eight bytes of an ILA IPv6 address).

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/net/checksum.h |  3 +++
 net/core/utils.c       | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/net/checksum.h b/include/net/checksum.h
index 2d1d73c..af76b8e 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -141,6 +141,9 @@ static inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new)
 struct sk_buff;
 void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
 			      __be32 from, __be32 to, int pseudohdr);
+void inet_proto_csum_replace8(__sum16 *sum, struct sk_buff *skb,
+			      const __be32 *from, const __be32 *to,
+			      int pseudohdr);
 void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
 			       const __be32 *from, const __be32 *to,
 			       int pseudohdr);
diff --git a/net/core/utils.c b/net/core/utils.c
index a7732a0..79d1067 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -336,6 +336,25 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
 }
 EXPORT_SYMBOL(inet_proto_csum_replace16);
 
+void inet_proto_csum_replace8(__sum16 *sum, struct sk_buff *skb,
+			      const __be32 *from, const __be32 *to,
+			      int pseudohdr)
+{
+	__be32 diff[] = {
+		~from[0], ~from[1], to[0], to[1],
+	};
+	if (skb->ip_summed != CHECKSUM_PARTIAL) {
+		*sum = csum_fold(csum_partial(diff, sizeof(diff),
+				 ~csum_unfold(*sum)));
+		if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
+			skb->csum = ~csum_partial(diff, sizeof(diff),
+						  ~skb->csum);
+	} else if (pseudohdr)
+		*sum = ~csum_fold(csum_partial(diff, sizeof(diff),
+				  csum_unfold(*sum)));
+}
+EXPORT_SYMBOL(inet_proto_csum_replace8);
+
 struct __net_random_once_work {
 	struct work_struct work;
 	struct static_key *key;
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC net-next 2/6] net: Identfier Locator Addressing module
  2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
  2015-06-03 19:58 ` [RFC net-next 1/6] net: Checksum functions to replace 8 bytes at a time Tom Herbert
@ 2015-06-03 19:58 ` Tom Herbert
  2015-06-04  8:58   ` Thomas Graf
  2015-06-04 10:02   ` Hannes Frederic Sowa
  2015-06-03 19:58 ` [RFC net-next 3/6] net: Special routing hook Tom Herbert
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 12+ messages in thread
From: Tom Herbert @ 2015-06-03 19:58 UTC (permalink / raw)
  To: davem, agartrell, maheshb, tgraf, netdev

Adding new module name ila. This implements ILA tanslation. A netlink
interface is used to configure identifier to lacator mappings. Two
functions are exported to attempt to perform a translation on input
or output path.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/net/ila.h |   7 +
 net/ipv6/Kconfig  |   8 +
 net/ipv6/Makefile |   1 +
 net/ipv6/ila.c    | 496 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 512 insertions(+)
 create mode 100644 include/net/ila.h
 create mode 100644 net/ipv6/ila.c

diff --git a/include/net/ila.h b/include/net/ila.h
new file mode 100644
index 0000000..25660c6
--- /dev/null
+++ b/include/net/ila.h
@@ -0,0 +1,7 @@
+#ifndef __NET_ILA_H
+#define __NET_ILA_H
+
+int ila_xlat_incoming(struct sk_buff *skb);
+int ila_xlat_outgoing(struct sk_buff *skb);
+
+#endif
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 438a73a..609ca1a 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -93,6 +93,14 @@ config IPV6_MIP6
 
 	  If unsure, say N.
 
+config IPV6_ILA
+	tristate "IPv6: Identifier Locator Addressing (ILA)"
+	---help---
+	  Support for IPv6 Identifier Locator Addressing described in
+	  https://tools.ietf.org/html/draft-herbert-nvo3-ila-00.
+
+	  If unsure, say N.
+
 config INET6_XFRM_TUNNEL
 	tristate
 	select INET6_TUNNEL
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 0f3f199..2c900c7 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
 obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
 obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
 obj-$(CONFIG_IPV6_MIP6) += mip6.o
+obj-$(CONFIG_IPV6_ILA) += ila.o
 obj-$(CONFIG_NETFILTER)	+= netfilter/
 
 obj-$(CONFIG_IPV6_VTI) += ip6_vti.o
diff --git a/net/ipv6/ila.c b/net/ipv6/ila.c
new file mode 100644
index 0000000..54a215d
--- /dev/null
+++ b/net/ipv6/ila.c
@@ -0,0 +1,496 @@
+#include <linux/errno.h>
+#include <linux/ip.h>
+#include <linux/jhash.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/rcupdate.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/genetlink.h>
+#include <net/ila.h>
+#include <net/ip.h>
+#include <net/netns/generic.h>
+#include <net/protocol.h>
+#include <uapi/linux/genetlink.h>
+#include <uapi/linux/ila.h>
+
+struct ila_map {
+	u64	identifier;
+	u64	locator;
+	struct hlist_node hlnode;
+	struct rcu_head rcu;
+};
+
+struct ila_map_bucket {
+	struct hlist_head chain;
+	spinlock_t lock;
+};
+
+#define ILA_HASH_TABLE_SIZE 1024
+
+struct ila_maps_info {
+	struct ila_map_bucket buckets[ILA_HASH_TABLE_SIZE];
+	unsigned int mask;
+	size_t size;
+};
+
+struct ila_cfg {
+	u64 identifier;
+	u64 locator;
+};
+
+static unsigned int ila_net_id;
+
+struct ila_net {
+	struct ila_maps_info info;
+};
+
+static struct genl_family ila_nl_family = {
+	.id		= GENL_ID_GENERATE,
+	.hdrsize	= 0,
+	.name		= ILA_GENL_NAME,
+	.version	= ILA_GENL_VERSION,
+	.maxattr	= ILA_ATTR_MAX,
+	.netnsok	= true,
+};
+
+static struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
+	[ILA_ATTR_IDENTIFIER] = { .type = NLA_U64, },
+	[ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
+};
+
+static u32 hashrnd __read_mostly;
+static __always_inline void ila_init_secret(void)
+{
+	net_get_random_once(&hashrnd, sizeof(hashrnd));
+}
+
+static inline unsigned int ila_hash(u64 id)
+{
+	u32 *words = (u32 *)&id;
+
+	return jhash_2words(words[0], words[1], hashrnd);
+}
+
+static int parse_nl_config(struct genl_info *info,
+			   struct ila_cfg *cfg)
+{
+	memset(cfg, 0, sizeof(*cfg));
+
+	if (info->attrs[ILA_ATTR_IDENTIFIER]) {
+		u64 identifier = nla_get_u64(info->attrs[ILA_ATTR_IDENTIFIER]);
+
+		cfg->identifier = identifier;
+	}
+
+	if (info->attrs[ILA_ATTR_LOCATOR]) {
+		u64 locator = nla_get_u64(info->attrs[ILA_ATTR_LOCATOR]);
+
+		cfg->locator = locator;
+	}
+
+	return 0;
+}
+
+/* Must be called with rcu readlock */
+struct ila_map *ila_lookup(u64 id, struct ila_maps_info *info)
+{
+	unsigned int hash = ila_hash(id);
+	unsigned int slot = hash & info->mask;
+	struct ila_map_bucket *head = &info->buckets[slot];
+	struct ila_map *ila;
+
+	hlist_for_each_entry_rcu(ila, &head->chain, hlnode) {
+		if (ila->identifier == id)
+			return ila;
+	}
+
+	return NULL;
+}
+
+/* Called with lock held for hlist */
+static inline void ila_release(struct ila_map *ila)
+{
+	hlist_del_init_rcu(&ila->hlnode);
+	kfree_rcu(ila, rcu);
+}
+
+static int ila_del_mapping(struct net *net, struct ila_cfg *cfg)
+{
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+	unsigned int hash = ila_hash(cfg->identifier);
+	struct ila_maps_info *info = &ilan->info;
+	struct ila_map_bucket *ilab = &info->buckets[hash & info->mask];
+	struct ila_map *ila;
+
+	spin_lock(&ilab->lock);
+
+	ila = ila_lookup(cfg->identifier, info);
+	if (ila)
+		ila_release(ila);
+
+	spin_unlock(&ilab->lock);
+
+	return 0;
+}
+
+static int ila_add_mapping(struct net *net, struct ila_cfg *cfg)
+{
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+	unsigned int hash = ila_hash(cfg->identifier);
+	struct ila_maps_info *info = &ilan->info;
+	struct ila_map_bucket *ilab = &info->buckets[hash & info->mask];
+	struct ila_map *ila, *ila_tmp;
+
+	ila = kzalloc(sizeof(*ila), GFP_KERNEL);
+	if (!ila)
+		return -ENOMEM;
+
+	ila->identifier = cfg->identifier;
+	ila->locator = cfg->locator;
+
+	spin_lock(&ilab->lock);
+
+	hlist_for_each_entry_rcu(ila_tmp, &ilab->chain, hlnode) {
+		if (ila_tmp->identifier == cfg->identifier) {
+			/* There's already a mapping for this locator,
+			 * delete for for now. Later just modify it in place?
+			 */
+			ila_release(ila_tmp);
+		}
+	}
+
+	if (hlist_unhashed(&ila->hlnode))
+		hlist_add_head_rcu(&ila->hlnode, &ilab->chain);
+
+	spin_unlock(&ilab->lock);
+
+	return 0;
+}
+
+static int ila_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = genl_info_net(info);
+	struct ila_cfg cfg;
+	int err;
+
+	err = parse_nl_config(info, &cfg);
+	if (err)
+		return err;
+
+	return ila_add_mapping(net, &cfg);
+}
+
+static int ila_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = genl_info_net(info);
+	struct ila_cfg cfg;
+	int err;
+
+	err = parse_nl_config(info, &cfg);
+	if (err)
+		return err;
+
+	return ila_del_mapping(net, &cfg);
+}
+
+static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg)
+{
+	if (nla_put_u64(msg, ILA_ATTR_IDENTIFIER, ila->identifier) ||
+	    nla_put_u64(msg, ILA_ATTR_LOCATOR, ila->locator))
+		return -1;
+
+	return 0;
+}
+
+static int ila_dump_info(struct ila_map *ila, u32 portid, u32 seq,
+			 u32 flags, struct sk_buff *skb, u8 cmd)
+{
+	void *hdr;
+
+	hdr = genlmsg_put(skb, portid, seq, &ila_nl_family, flags, cmd);
+	if (!hdr)
+		return -ENOMEM;
+
+	if (ila_fill_info(ila, skb) < 0)
+		goto nla_put_failure;
+
+	genlmsg_end(skb, hdr);
+	return 0;
+
+nla_put_failure:
+	genlmsg_cancel(skb, hdr);
+	return -EMSGSIZE;
+}
+
+static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = genl_info_net(info);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+	struct sk_buff *msg;
+	struct ila_cfg cfg;
+	struct ila_map *ila;
+	int ret;
+
+	ret = parse_nl_config(info, &cfg);
+	if (ret)
+		return ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	rcu_read_lock();
+
+	ila = ila_lookup(cfg.identifier, &ilan->info);
+	if (ila) {
+		ret = ila_dump_info(ila, info->snd_portid,
+				    info->snd_seq, 0, msg,
+				    info->genlhdr->cmd);
+	}
+
+	rcu_read_unlock();
+
+	if (ret < 0)
+		goto out_free;
+
+	return genlmsg_reply(msg, info);
+
+out_free:
+	nlmsg_free(msg);
+	return ret;
+}
+
+static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct net *net = sock_net(skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+	struct ila_maps_info *info = &ilan->info;
+	struct ila_map *ila;
+	int idx = 0;
+	int i;
+
+	for (i = 0; i < info->size; i++) {
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(ila, &info->buckets[i].chain, hlnode) {
+			if (idx < cb->args[0])
+				goto skip;
+			if (ila_dump_info(ila, NETLINK_CB(cb->skb).portid,
+					  cb->nlh->nlmsg_seq, NLM_F_MULTI,
+					  skb, ILA_CMD_GET) < 0)
+				break;
+skip:
+			idx++;
+		}
+		rcu_read_unlock();
+	}
+
+	cb->args[0] = idx;
+	return skb->len;
+}
+
+static const struct genl_ops ila_nl_ops[] = {
+	{
+		.cmd = ILA_CMD_ADD,
+		.doit = ila_nl_cmd_add_mapping,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = ILA_CMD_DEL,
+		.doit = ila_nl_cmd_del_mapping,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = ILA_CMD_GET,
+		.doit = ila_nl_cmd_get_mapping,
+		.dumpit = ila_nl_dump,
+		.policy = ila_nl_policy,
+	},
+};
+
+#define ILA_HASH_TABLE_SIZE 1024
+
+void ila_hashinfo_init(struct ila_maps_info *info)
+{
+	int i;
+
+	memset(info, 0, sizeof(*info));
+
+	info->size = ILA_HASH_TABLE_SIZE;
+	info->mask = ILA_HASH_TABLE_SIZE - 1;
+
+	for (i = 0; i < ILA_HASH_TABLE_SIZE; i++) {
+		struct ila_map_bucket *ilab = &info->buckets[i];
+
+		spin_lock_init(&ilab->lock);
+		INIT_HLIST_HEAD(&ilab->chain);
+	}
+}
+
+static __net_init int ila_init_net(struct net *net)
+{
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	ila_hashinfo_init(&ilan->info);
+
+	return 0;
+}
+
+static __net_exit void ila_exit_net(struct net *net)
+{
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+	struct ila_maps_info *info = &ilan->info;
+	struct ila_map *ila;
+	struct hlist_node *tmp;
+	int i;
+
+	for (i = 0; i < info->size; i++) {
+		struct ila_map_bucket *ilab = &info->buckets[i];
+
+		spin_lock(&ilab->lock);
+
+		hlist_for_each_entry_safe(ila, tmp, &ilab->chain, hlnode) {
+			ila_release(ila);
+		}
+
+		spin_unlock(&ilab->lock);
+	}
+
+	info->size = 0;
+}
+
+static struct pernet_operations ila_net_ops = {
+	.init = ila_init_net,
+	.exit = ila_exit_net,
+	.id   = &ila_net_id,
+	.size = sizeof(struct ila_net),
+};
+
+static int __init ila_init(void)
+{
+	int ret;
+
+	ila_init_secret();
+
+	ret = register_pernet_device(&ila_net_ops);
+	if (ret)
+		goto exit;
+
+	ret = genl_register_family_with_ops(&ila_nl_family,
+					    ila_nl_ops);
+	if (ret < 0)
+		goto unregister;
+
+	return 0;
+
+unregister:
+	unregister_pernet_device(&ila_net_ops);
+exit:
+	return ret;
+}
+
+static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
+				 __be32 loc[2], const __be32 new_loc[2])
+{
+	int nhoff = sizeof(struct ipv6hdr);
+
+	switch (l4_proto) {
+	case NEXTHDR_TCP:
+		if (likely(pskb_may_pull(skb, nhoff + sizeof(struct tcphdr)))) {
+			struct tcphdr *th = (struct tcphdr *)
+					(skb_network_header(skb) + nhoff);
+
+			inet_proto_csum_replace8(&th->check, skb,
+						 loc, new_loc, 1);
+		}
+		break;
+	case NEXTHDR_UDP:
+		if (likely(pskb_may_pull(skb, nhoff + sizeof(struct udphdr)))) {
+			struct udphdr *uh = (struct udphdr *)
+					(skb_network_header(skb) + nhoff);
+
+			if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {
+				inet_proto_csum_replace8(&uh->check, skb,
+							 loc, new_loc, 1);
+				if (!uh->check)
+					uh->check = CSUM_MANGLED_0;
+			}
+		}
+		break;
+	case NEXTHDR_ICMP:
+		if (likely(pskb_may_pull(skb,
+					 nhoff + sizeof(struct icmp6hdr)))) {
+			struct icmp6hdr *ih = (struct icmp6hdr *)
+					(skb_network_header(skb) + nhoff);
+
+			inet_proto_csum_replace8(&ih->icmp6_cksum,
+						 skb, loc, new_loc, 1);
+		}
+		break;
+	}
+}
+
+static void nat_locator(struct sk_buff *skb, struct ipv6hdr *ip6h, u64 locator)
+{
+	__be32 *words = (__be32 *)&locator;
+
+	update_ipv6_checksum(skb, ip6h->nexthdr, (__be32 *)&ip6h->daddr, words);
+	memcpy(&ip6h->daddr, words, sizeof(locator));
+}
+
+static void __exit ila_fini(void)
+{
+	genl_unregister_family(&ila_nl_family);
+	unregister_pernet_device(&ila_net_ops);
+}
+
+static int __ila_xlat(struct sk_buff *skb, struct net *net)
+{
+	struct ila_map *ila;
+	struct ipv6hdr *ip6h;
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+	struct ila_maps_info *info = &ilan->info;
+	u64 identifier;
+
+	if (skb->protocol != htons(ETH_P_IPV6))
+		return 0;
+
+	if (unlikely(!pskb_may_pull(skb, sizeof(*ip6h))))
+		return 0;
+
+	ip6h = ipv6_hdr(skb);
+	if (ip6h->version != 6)
+		return 0;
+
+	identifier = *(u64 *)&ip6h->daddr.in6_u.u6_addr8[8];
+	ila = ila_lookup(identifier, info);
+	if (ila)
+		nat_locator(skb, ip6h, ila->locator);
+
+	return 0;
+}
+
+int ila_xlat_outgoing(struct sk_buff *skb)
+{
+	struct net *net = dev_net(skb_dst(skb)->dev);
+
+	return __ila_xlat(skb, net);
+}
+EXPORT_SYMBOL(ila_xlat_outgoing);
+
+int ila_xlat_incoming(struct sk_buff *skb)
+{
+	struct net *net = dev_net(skb->dev);
+
+	return __ila_xlat(skb, net);
+}
+EXPORT_SYMBOL(ila_xlat_incoming);
+
+module_init(ila_init);
+module_exit(ila_fini);
+MODULE_AUTHOR("Tom Herbert <tom@herbertland.com>");
+MODULE_LICENSE("GPL");
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC net-next 3/6] net: Special routing hook
  2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
  2015-06-03 19:58 ` [RFC net-next 1/6] net: Checksum functions to replace 8 bytes at a time Tom Herbert
  2015-06-03 19:58 ` [RFC net-next 2/6] net: Identfier Locator Addressing module Tom Herbert
@ 2015-06-03 19:58 ` Tom Herbert
  2015-06-04  7:40   ` Hannes Frederic Sowa
  2015-06-03 19:58 ` [RFC net-next 4/6] net: ILA use special route hook Tom Herbert
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Tom Herbert @ 2015-06-03 19:58 UTC (permalink / raw)
  To: davem, agartrell, maheshb, tgraf, netdev

A hack to provide an ultra light weight hook to do translations.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/net/ip6_route.h | 22 +++++++++++++++++++++
 net/ipv6/ip6_input.c    |  3 +++
 net/ipv6/ip6_output.c   | 24 ++++++++++++++++++++++-
 net/ipv6/route.c        | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/xfrm6_input.c  |  4 ++++
 5 files changed, 103 insertions(+), 1 deletion(-)

diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 297629a..d6efa67 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -156,6 +156,28 @@ static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
 	spin_unlock(&sk->sk_dst_lock);
 }
 
+struct special_route {
+	int (*input)(struct sk_buff *skb);
+	int (*output)(struct sk_buff *skb);
+	struct list_head list;
+};
+
+extern struct list_head route_special_head __read_mostly;
+
+void ip6_route_special_add(struct special_route *sr);
+void ip6_route_special_remove(struct special_route *sr);
+int __ip6_route_special(struct sk_buff *skb, bool output);
+
+static inline int ip6_route_special_input(struct sk_buff *skb)
+{
+	return __ip6_route_special(skb, false);
+}
+
+static inline int ip6_route_special_output(struct sk_buff *skb)
+{
+	return __ip6_route_special(skb, true);
+}
+
 static inline bool ipv6_unicast_destination(const struct sk_buff *skb)
 {
 	struct rt6_info *rt = (struct rt6_info *) skb_dst(skb);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index f2e464e..d0a61cc 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -177,6 +177,9 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 		}
 	}
 
+	if (ip6_route_special_input(skb) < 0)
+		goto drop;
+
 	rcu_read_unlock();
 
 	/* Must drop socket now because of tproxy. */
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index d5f7716..857c873 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -77,13 +77,28 @@ static int ip6_finish_output2(struct sock *sk, struct sk_buff *skb)
 					 &ipv6_hdr(skb)->saddr))) {
 			struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
 
+			if (ip6_route_special_output(skb) < 0) {
+				IP6_INC_STATS(dev_net(dev), idev,
+					      IPSTATS_MIB_OUTDISCARDS);
+				kfree_skb(skb);
+				return 0;
+			}
+
 			/* Do not check for IFF_ALLMULTI; multicast routing
 			   is not supported in any case.
 			 */
-			if (newskb)
+			if (newskb) {
+				if (ip6_route_special_output(skb) < 0) {
+					IP6_INC_STATS(dev_net(dev), idev,
+						      IPSTATS_MIB_OUTDISCARDS);
+					kfree_skb(skb);
+					return 0;
+				}
+
 				NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING,
 					sk, newskb, NULL, newskb->dev,
 					dev_loopback_xmit);
+			}
 
 			if (ipv6_hdr(skb)->hop_limit == 0) {
 				IP6_INC_STATS(dev_net(dev), idev,
@@ -143,6 +158,13 @@ int ip6_output(struct sock *sk, struct sk_buff *skb)
 		return 0;
 	}
 
+	if (ip6_route_special_output(skb) < 0) {
+		IP6_INC_STATS(dev_net(dev), idev,
+			      IPSTATS_MIB_OUTDISCARDS);
+		kfree_skb(skb);
+		return 0;
+	}
+
 	return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, sk, skb,
 			    NULL, dev,
 			    ip6_finish_output,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1a1122a..e6096e0 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -44,6 +44,7 @@
 #include <linux/seq_file.h>
 #include <linux/nsproxy.h>
 #include <linux/slab.h>
+#include <linux/list.h>
 #include <net/net_namespace.h>
 #include <net/snmp.h>
 #include <net/ipv6.h>
@@ -2590,6 +2591,54 @@ void rt6_mtu_change(struct net_device *dev, unsigned int mtu)
 	fib6_clean_all(dev_net(dev), rt6_mtu_change_route, &arg);
 }
 
+struct list_head route_special_head __read_mostly;
+static DEFINE_SPINLOCK(special_route_lock);
+
+void ip6_route_special_add(struct special_route *sr)
+{
+	spin_lock(&special_route_lock);
+	list_add_rcu(&sr->list, &route_special_head);
+	spin_unlock(&special_route_lock);
+}
+EXPORT_SYMBOL(ip6_route_special_add);
+
+void ip6_route_special_remove(struct special_route *sr)
+{
+	struct special_route *sr1;
+
+	spin_lock(&special_route_lock);
+
+	list_for_each_entry_rcu(sr1, &route_special_head, list) {
+		if (sr == sr1) {
+			list_del_rcu(&sr->list);
+			goto out;
+		}
+	}
+
+	pr_warn("route_special_remove: %p not found\n", sr);
+out:
+	spin_unlock(&special_route_lock);
+}
+EXPORT_SYMBOL(ip6_route_special_remove);
+
+int __ip6_route_special(struct sk_buff *skb, bool output)
+{
+	struct special_route *sr;
+	int ret = 0;
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(sr, &route_special_head, list) {
+		ret = output ? sr->output(skb) : sr->input(skb);
+		if (ret < 0)
+			break;
+	}
+
+	rcu_read_lock();
+	return ret;
+}
+EXPORT_SYMBOL(__ip6_route_special);
+
 static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
 	[RTA_GATEWAY]           = { .len = sizeof(struct in6_addr) },
 	[RTA_OIF]               = { .type = NLA_U32 },
@@ -3488,6 +3537,8 @@ int __init ip6_route_init(void)
 		spin_lock_init(&ul->lock);
 	}
 
+	INIT_LIST_HEAD(&route_special_head);
+
 out:
 	return ret;
 
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 74bd178..d1f75b8 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -14,6 +14,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
 #include <net/ipv6.h>
+#include <net/ip6_route.h>
 #include <net/xfrm.h>
 
 int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
@@ -42,6 +43,9 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
 	ipv6_hdr(skb)->payload_len = htons(skb->len);
 	__skb_push(skb, skb->data - skb_network_header(skb));
 
+	if (ip6_route_special_input(skb) < 0)
+		return 1;
+
 	NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, NULL, skb,
 		skb->dev, NULL,
 		ip6_rcv_finish);
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC net-next 4/6] net: ILA use special route hook
  2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
                   ` (2 preceding siblings ...)
  2015-06-03 19:58 ` [RFC net-next 3/6] net: Special routing hook Tom Herbert
@ 2015-06-03 19:58 ` Tom Herbert
  2015-06-03 19:58 ` [RFC net-next 5/6] net: ILA iptables target Tom Herbert
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Tom Herbert @ 2015-06-03 19:58 UTC (permalink / raw)
  To: davem, agartrell, maheshb, tgraf, netdev

Register hooks from ILA.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/ipv6/ila.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/net/ipv6/ila.c b/net/ipv6/ila.c
index 54a215d..d6fce77 100644
--- a/net/ipv6/ila.c
+++ b/net/ipv6/ila.c
@@ -11,11 +11,16 @@
 #include <net/genetlink.h>
 #include <net/ila.h>
 #include <net/ip.h>
+#include <net/ip6_route.h>
 #include <net/netns/generic.h>
 #include <net/protocol.h>
 #include <uapi/linux/genetlink.h>
 #include <uapi/linux/ila.h>
 
+static bool special_route;
+module_param(special_route, bool, 0644);
+MODULE_PARM_DESC(special_route, "Set up special route hook");
+
 struct ila_map {
 	u64	identifier;
 	u64	locator;
@@ -370,12 +375,19 @@ static struct pernet_operations ila_net_ops = {
 	.size = sizeof(struct ila_net),
 };
 
+struct special_route ila_route_special = {
+	.input = ila_xlat_incoming,
+	.output = ila_xlat_outgoing,
+};
+
 static int __init ila_init(void)
 {
 	int ret;
 
 	ila_init_secret();
 
+	ip6_route_special_add(&ila_route_special);
+
 	ret = register_pernet_device(&ila_net_ops);
 	if (ret)
 		goto exit;
@@ -444,6 +456,7 @@ static void nat_locator(struct sk_buff *skb, struct ipv6hdr *ip6h, u64 locator)
 
 static void __exit ila_fini(void)
 {
+	ip6_route_special_remove(&ila_route_special);
 	genl_unregister_family(&ila_nl_family);
 	unregister_pernet_device(&ila_net_ops);
 }
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC net-next 5/6] net: ILA iptables target
  2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
                   ` (3 preceding siblings ...)
  2015-06-03 19:58 ` [RFC net-next 4/6] net: ILA use special route hook Tom Herbert
@ 2015-06-03 19:58 ` Tom Herbert
  2015-06-03 19:58 ` [RFC net-next 6/6] ipvlan: Call ILA in incoming and outgoing receive paths Tom Herbert
  2015-06-04  9:00 ` [RFC net-next 0/6] net: Identifier Locator Addressing Thomas Graf
  6 siblings, 0 replies; 12+ messages in thread
From: Tom Herbert @ 2015-06-03 19:58 UTC (permalink / raw)
  To: davem, agartrell, maheshb, tgraf, netdev

Add two target ILAIN and ILAOUT which hook into the ILA module.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/netfilter/Kconfig  | 11 +++++++
 net/netfilter/Makefile |  1 +
 net/netfilter/xt_ILA.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+)
 create mode 100644 net/netfilter/xt_ILA.c

diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index fbc8d15..eaf7d68 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -748,6 +748,17 @@ config NETFILTER_XT_TARGET_IDLETIMER
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_ILA
+	tristate "ILA target support"
+	depends on IP_NF_MANGLE || IP6_NF_MANGLE
+	depends on NETFILTER_ADVANCED
+	help
+	  This option adds an `ILA' target, which allow Identifier Locator
+	  Addressing (ILA) translations. The ILA tables are managed by the
+	  ILA module.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_TARGET_LED
 	tristate '"LED" target support'
 	depends on LEDS_CLASS && LEDS_TRIGGERS
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 70d026d..d99740a 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -124,6 +124,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_ILA) += xt_ILA.o
 
 # matches
 obj-$(CONFIG_NETFILTER_XT_MATCH_ADDRTYPE) += xt_addrtype.o
diff --git a/net/netfilter/xt_ILA.c b/net/netfilter/xt_ILA.c
new file mode 100644
index 0000000..0d92c8f
--- /dev/null
+++ b/net/netfilter/xt_ILA.c
@@ -0,0 +1,82 @@
+/* x_tables module for Identifier Locator Addressing (ILA) translation
+ *
+ * (C) 2015 by Tom Herbert <tom@herbertland.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <net/ila.h>
+
+#include <linux/netfilter/x_tables.h>
+
+MODULE_AUTHOR("Tom Herbert <tom@herbertland.com>");
+MODULE_DESCRIPTION("Xtables: ILA translation");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ip6t_ILA");
+MODULE_ALIAS("ip6t_ILAIN");
+MODULE_ALIAS("ip6t_ILAOUT");
+
+static unsigned int
+ila_tg_input(struct sk_buff *skb, const struct xt_action_param *par)
+{
+	ila_xlat_incoming(skb);
+
+	return XT_CONTINUE;
+}
+
+static unsigned int
+ila_tg_output(struct sk_buff *skb, const struct xt_action_param *par)
+{
+	ila_xlat_outgoing(skb);
+
+	return XT_CONTINUE;
+}
+
+static int ila_tg_check(const struct xt_tgchk_param *par)
+{
+	return 0;
+}
+
+static struct xt_target ila_tg_reg[] __read_mostly = {
+	{
+		.name		= "ILAIN",
+		.family		= NFPROTO_IPV6,
+		.checkentry	= ila_tg_check,
+		.target		= ila_tg_input,
+		.targetsize	= 32,
+		.table		= "mangle",
+		.hooks		= (1 << NF_INET_POST_ROUTING) |
+				  (1 << NF_INET_LOCAL_IN),
+		.me		= THIS_MODULE,
+	},
+	{
+		.name		= "ILAOUT",
+		.family		= NFPROTO_IPV6,
+		.checkentry	= ila_tg_check,
+		.target		= ila_tg_output,
+		.targetsize	= 32,
+		.table		= "mangle",
+		.hooks		= (1 << NF_INET_PRE_ROUTING) |
+				  (1 << NF_INET_LOCAL_OUT),
+		.me		= THIS_MODULE,
+	},
+};
+
+static int __init ila_tg_init(void)
+{
+	return xt_register_targets(ila_tg_reg, ARRAY_SIZE(ila_tg_reg));
+}
+
+static void __exit ila_tg_exit(void)
+{
+	xt_unregister_targets(ila_tg_reg, ARRAY_SIZE(ila_tg_reg));
+}
+
+module_init(ila_tg_init);
+module_exit(ila_tg_exit);
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC net-next 6/6] ipvlan: Call ILA in incoming and outgoing receive paths
  2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
                   ` (4 preceding siblings ...)
  2015-06-03 19:58 ` [RFC net-next 5/6] net: ILA iptables target Tom Herbert
@ 2015-06-03 19:58 ` Tom Herbert
  2015-06-04  8:58   ` Thomas Graf
  2015-06-04  9:00 ` [RFC net-next 0/6] net: Identifier Locator Addressing Thomas Graf
  6 siblings, 1 reply; 12+ messages in thread
From: Tom Herbert @ 2015-06-03 19:58 UTC (permalink / raw)
  To: davem, agartrell, maheshb, tgraf, netdev

Hacked IPVLAN to call ILA functions in send and receive paths.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ipvlan/ipvlan.h      |  1 +
 drivers/net/ipvlan/ipvlan_core.c | 27 ++++++++++++++++++---------
 drivers/net/ipvlan/ipvlan_main.c |  4 ++++
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 953a974..3b85260 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -28,6 +28,7 @@
 #include <net/rtnetlink.h>
 #include <net/route.h>
 #include <net/addrconf.h>
+#include <net/ila.h>
 
 #define IPVLAN_DRV	"ipvlan"
 #define IPV_DRV_VER	"0.1"
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 8afbeda..7e71907 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -9,6 +9,8 @@
 
 #include "ipvlan.h"
 
+extern bool query_ila;
+
 static u32 ipvlan_jhash_secret __read_mostly;
 
 void ipvlan_init_secret(void)
@@ -385,15 +387,18 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
 	struct net_device *dev = skb->dev;
 	struct dst_entry *dst;
 	int err, ret = NET_XMIT_DROP;
-	struct flowi6 fl6 = {
-		.flowi6_iif = skb->dev->ifindex,
-		.daddr = ip6h->daddr,
-		.saddr = ip6h->saddr,
-		.flowi6_flags = FLOWI_FLAG_ANYSRC,
-		.flowlabel = ip6_flowinfo(ip6h),
-		.flowi6_mark = skb->mark,
-		.flowi6_proto = ip6h->nexthdr,
-	};
+	struct flowi6 fl6;
+
+	if (query_ila && ila_xlat_outgoing(skb) < 0)
+		goto err;
+
+	fl6.flowi6_iif = skb->dev->ifindex;
+	fl6.daddr = ip6h->daddr;
+	fl6.saddr = ip6h->saddr;
+	fl6.flowi6_flags = FLOWI_FLAG_ANYSRC;
+	fl6.flowlabel = ip6_flowinfo(ip6h);
+	fl6.flowi6_mark = skb->mark;
+	fl6.flowi6_proto = ip6h->nexthdr;
 
 	dst = ip6_route_output(dev_net(dev), NULL, &fl6);
 	if (dst->error) {
@@ -401,6 +406,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
 		dst_release(dst);
 		goto err;
 	}
+
 	skb_dst_drop(skb);
 	skb_dst_set(skb, dst);
 	err = ip6_local_out(skb);
@@ -583,6 +589,9 @@ static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb,
 	struct sk_buff *skb = *pskb;
 	rx_handler_result_t ret = RX_HANDLER_PASS;
 
+	if (query_ila && ila_xlat_incoming(skb) < 0)
+		goto out;
+
 	lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
 	if (!lyr3h)
 		goto out;
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 1acc283..e029fad 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -9,6 +9,10 @@
 
 #include "ipvlan.h"
 
+bool query_ila = false;
+module_param(query_ila, bool, 0644);
+MODULE_PARM_DESC(query_ila, "Query ILA in incoming and outgoing paths");
+
 void ipvlan_adjust_mtu(struct ipvl_dev *ipvlan, struct net_device *dev)
 {
 	ipvlan->dev->mtu = dev->mtu - ipvlan->mtu_adj;
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RFC net-next 3/6] net: Special routing hook
  2015-06-03 19:58 ` [RFC net-next 3/6] net: Special routing hook Tom Herbert
@ 2015-06-04  7:40   ` Hannes Frederic Sowa
  0 siblings, 0 replies; 12+ messages in thread
From: Hannes Frederic Sowa @ 2015-06-04  7:40 UTC (permalink / raw)
  To: Tom Herbert, davem, agartrell, maheshb, tgraf, netdev

Hi,

On Wed, Jun 3, 2015, at 21:58, Tom Herbert wrote:
> A hack to provide an ultra light weight hook to do translations.

Would it be possible to use ip6_ila_input hooks in dst_entry to do those
translations? It really seems like a hack ;)

Bye,
Hannes

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC net-next 2/6] net: Identfier Locator Addressing module
  2015-06-03 19:58 ` [RFC net-next 2/6] net: Identfier Locator Addressing module Tom Herbert
@ 2015-06-04  8:58   ` Thomas Graf
  2015-06-04 10:02   ` Hannes Frederic Sowa
  1 sibling, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-06-04  8:58 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, agartrell, maheshb, netdev

On 06/03/15 at 12:58pm, Tom Herbert wrote:
> +static struct genl_family ila_nl_family = {
> +	.id		= GENL_ID_GENERATE,
> +	.hdrsize	= 0,
> +	.name		= ILA_GENL_NAME,
> +	.version	= ILA_GENL_VERSION,
> +	.maxattr	= ILA_ATTR_MAX,
> +	.netnsok	= true,
> +};

Since you have bucket locks, you might want to see if you can
enable .parallel_ops = true to speed up the rate of map updates.

Use of rhashtable is another obvious consideration.

> +static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
> +{
> +	struct net *net = genl_info_net(info);
> +	struct ila_net *ilan = net_generic(net, ila_net_id);
> +	struct sk_buff *msg;
> +	struct ila_cfg cfg;
> +	struct ila_map *ila;
> +	int ret;
> +
> +	ret = parse_nl_config(info, &cfg);
> +	if (ret)
> +		return ret;
> +
> +	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> +	if (!msg)
> +		return -ENOMEM;

Since the message size is actually really small it might be worth
to calculate it accurately here to speed up the get.

> +#define ILA_HASH_TABLE_SIZE 1024

Already defined at the top.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC net-next 6/6] ipvlan: Call ILA in incoming and outgoing receive paths
  2015-06-03 19:58 ` [RFC net-next 6/6] ipvlan: Call ILA in incoming and outgoing receive paths Tom Herbert
@ 2015-06-04  8:58   ` Thomas Graf
  0 siblings, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-06-04  8:58 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, agartrell, maheshb, netdev

On 06/03/15 at 12:58pm, Tom Herbert wrote:
> diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
> index 1acc283..e029fad 100644
> --- a/drivers/net/ipvlan/ipvlan_main.c
> +++ b/drivers/net/ipvlan/ipvlan_main.c
> @@ -9,6 +9,10 @@
>  
>  #include "ipvlan.h"
>  
> +bool query_ila = false;
> +module_param(query_ila, bool, 0644);
> +MODULE_PARM_DESC(query_ila, "Query ILA in incoming and outgoing paths");

Can we make this not a module param?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC net-next 0/6] net: Identifier Locator Addressing
  2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
                   ` (5 preceding siblings ...)
  2015-06-03 19:58 ` [RFC net-next 6/6] ipvlan: Call ILA in incoming and outgoing receive paths Tom Herbert
@ 2015-06-04  9:00 ` Thomas Graf
  6 siblings, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-06-04  9:00 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, agartrell, maheshb, netdev

On 06/03/15 at 12:58pm, Tom Herbert wrote:
> The data path for ILA is a simple NAT translation that only operates
> on the upper 64 bits of a destination address in IPv6 packets. The
> basic process is:
> 
>    1) Lookup 64 bit identifier (lower 64 bits of destination) in a table
>    2) If a match is found
>       a) Overwrite locator (upper 64 bits of destination) with
>          new locator
>       b) Adjust any checksum that has destination address included in
>          pseudo header
>    3) Send or receive packet

Nice. I like this a lot!

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC net-next 2/6] net: Identfier Locator Addressing module
  2015-06-03 19:58 ` [RFC net-next 2/6] net: Identfier Locator Addressing module Tom Herbert
  2015-06-04  8:58   ` Thomas Graf
@ 2015-06-04 10:02   ` Hannes Frederic Sowa
  1 sibling, 0 replies; 12+ messages in thread
From: Hannes Frederic Sowa @ 2015-06-04 10:02 UTC (permalink / raw)
  To: Tom Herbert, davem, agartrell, maheshb, tgraf, netdev

On Wed, Jun 3, 2015, at 21:58, Tom Herbert wrote:
> +static u32 hashrnd __read_mostly;
> +static __always_inline void ila_init_secret(void)
> +{
> +       net_get_random_once(&hashrnd, sizeof(hashrnd));
> +}
> +
> +static inline unsigned int ila_hash(u64 id)
> +{
> +       u32 *words = (u32 *)&id;
> +
> +       return jhash_2words(words[0], words[1], hashrnd);
> +}

You can put hashrnd as static variable inside ila_hash and use the
net_get_random_once directly before calling jhash, no need to initialize
the secret during kernel bootup.

Thanks,
Hannes

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-06-04 10:02 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-03 19:58 [RFC net-next 0/6] net: Identifier Locator Addressing Tom Herbert
2015-06-03 19:58 ` [RFC net-next 1/6] net: Checksum functions to replace 8 bytes at a time Tom Herbert
2015-06-03 19:58 ` [RFC net-next 2/6] net: Identfier Locator Addressing module Tom Herbert
2015-06-04  8:58   ` Thomas Graf
2015-06-04 10:02   ` Hannes Frederic Sowa
2015-06-03 19:58 ` [RFC net-next 3/6] net: Special routing hook Tom Herbert
2015-06-04  7:40   ` Hannes Frederic Sowa
2015-06-03 19:58 ` [RFC net-next 4/6] net: ILA use special route hook Tom Herbert
2015-06-03 19:58 ` [RFC net-next 5/6] net: ILA iptables target Tom Herbert
2015-06-03 19:58 ` [RFC net-next 6/6] ipvlan: Call ILA in incoming and outgoing receive paths Tom Herbert
2015-06-04  8:58   ` Thomas Graf
2015-06-04  9:00 ` [RFC net-next 0/6] net: Identifier Locator Addressing Thomas Graf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).