* [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* 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 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
* [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* 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
* [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 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