netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp
@ 2016-09-23 17:16 Alexei Starovoitov
  2016-09-23 17:16 ` [PATCH RFC 1/2] samples/bpf: ilarouter for tc Alexei Starovoitov
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Alexei Starovoitov @ 2016-09-23 17:16 UTC (permalink / raw)
  To: David S . Miller
  Cc: Daniel Borkmann, Jesper Dangaard Brouer, Tom Herbert,
	Jamal Hadi Salim, Thomas Graf, netdev

From: Aaron Yue <haoxuany@andrew.cmu.edu>

Jesper,

here is old email and cover letter that didn't make it to the list
due to vger outage (I guess).
The verifier patch that Aaron is talking about has landed long ago.

The dataplane of ILA router is very short and simple.
Control plane is very different matter. It's not ready for prime time yet.

----------

This patch contains the tc and xdp implementation of kernelspace bpf code.
It requires userspace to insert to the ILA bpf maps, in tc's case, the 
precomputed ILA mappings, and in xdp's case, both the precomputed ILA
mappings and the MAC address.

The xdp bpf code also requires a verifier patch to allow direct map access
from the packet (will be patched in by Alexei).

Aaron Yue (2):
  samples/bpf: ilarouter for tc
  samples/bpf: ilarouter for xdp

 samples/bpf/Makefile        |   2 +
 samples/bpf/ila.h           |  80 ++++++++++++++++++++++++++++
 samples/bpf/ilarouter_tc.c  | 124 ++++++++++++++++++++++++++++++++++++++++++++
 samples/bpf/ilarouter_xdp.c |  88 +++++++++++++++++++++++++++++++
 samples/bpf/inet_helper.h   |  38 ++++++++++++++
 5 files changed, 332 insertions(+)
 create mode 100644 samples/bpf/ila.h
 create mode 100644 samples/bpf/ilarouter_tc.c
 create mode 100644 samples/bpf/ilarouter_xdp.c
 create mode 100644 samples/bpf/inet_helper.h

-- 
2.8.0.rc2

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

* [PATCH RFC 1/2] samples/bpf: ilarouter for tc
  2016-09-23 17:16 [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp Alexei Starovoitov
@ 2016-09-23 17:16 ` Alexei Starovoitov
  2016-09-23 17:16 ` [PATCH RFC 2/2] samples/bpf: ilarouter for xdp Alexei Starovoitov
  2016-09-23 18:06 ` [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp Jesper Dangaard Brouer
  2 siblings, 0 replies; 4+ messages in thread
From: Alexei Starovoitov @ 2016-09-23 17:16 UTC (permalink / raw)
  To: David S . Miller
  Cc: Daniel Borkmann, Jesper Dangaard Brouer, Tom Herbert,
	Jamal Hadi Salim, Thomas Graf, netdev

From: Aaron Yue <haoxuany@andrew.cmu.edu>

From: Aaron Yue <haoxuany@fb.com>

Requires a userspace program to insert ila mappings to the ila map.

Signed-off-by: Aaron Yue <haoxuany@fb.com>
Signed-off-by: Aaron Yue <haoxuany@andrew.cmu.edu>
---
 samples/bpf/Makefile       |   1 +
 samples/bpf/ila.h          |  80 +++++++++++++++++++++++++++++
 samples/bpf/ilarouter_tc.c | 124 +++++++++++++++++++++++++++++++++++++++++++++
 samples/bpf/inet_helper.h  |  38 ++++++++++++++
 4 files changed, 243 insertions(+)
 create mode 100644 samples/bpf/ila.h
 create mode 100644 samples/bpf/ilarouter_tc.c
 create mode 100644 samples/bpf/inet_helper.h

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 90ebf7d..15e19bb 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -74,6 +74,7 @@ always += parse_varlen.o parse_simple.o parse_ldabs.o
 always += test_cgrp2_tc_kern.o
 always += xdp1_kern.o
 always += xdp2_kern.o
+always += ilarouter_tc.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
diff --git a/samples/bpf/ila.h b/samples/bpf/ila.h
new file mode 100644
index 0000000..39a11f8
--- /dev/null
+++ b/samples/bpf/ila.h
@@ -0,0 +1,80 @@
+#ifndef _SIR_H
+#define _SIR_H
+
+#include <linux/types.h>
+#include <linux/in6.h>
+#include <asm/byteorder.h>
+
+#define SIR_T_LOCAL 0x1
+#define SIR_T_VIRTUAL 0x3
+
+struct in6_addr_sir {
+	__be64 prefix;
+	__be64 identifier_c_type;
+} __packed;
+
+struct in6_addr_ila {
+	__be64 locator;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	__u8 identifier:4,
+	     c:1,
+	     type:3;
+	__u8  identifier2;
+	__be16 identifier3;
+	__be16 identifier4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+	__be32 type:3,
+	       c:1,
+	       identifier:28;
+	__be16 identifier2;
+#else
+#error "Fix asm/byteorder.h"
+#endif
+	__be16 checksum;
+} __packed;
+
+struct sirhdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	__u16 traffic_class:4,
+	version:4,
+	flow_label:4,
+	traffic_class2:4;
+	__be16 flow_label2;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+	__u32 version:4,
+	      traffic_class:8,
+	      flow_label:20;
+#else
+#error "Fix asm/byteorder.h"
+#endif
+	__be16 payload_length;
+	__u8   next_header;
+	__u8   hop_limit;
+
+	struct in6_addr source_address;
+	struct in6_addr_sir destination_address;
+} __packed;
+
+struct ilahdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	__u16 traffic_class:4,
+	version:4,
+	flow_label:4,
+	traffic_class2:4;
+	__be16 flow_label2;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+	__u32 version:4,
+	      traffic_class:8,
+	      flow_label:20;
+#else
+#error "Fix asm/byteorder.h"
+#endif
+	__be16 payload_length;
+	__u8   next_header;
+	__u8   hop_limit;
+
+	struct in6_addr source_address;
+	struct in6_addr_ila destination_address;
+} __packed;
+
+#endif
diff --git a/samples/bpf/ilarouter_tc.c b/samples/bpf/ilarouter_tc.c
new file mode 100644
index 0000000..277322e
--- /dev/null
+++ b/samples/bpf/ilarouter_tc.c
@@ -0,0 +1,124 @@
+/* Copyright (c) 2016 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#define MAP_SIZE (1 << 20)
+
+#define KBUILD_MODNAME "ilarouter"
+#include <linux/if_ether.h>
+#include <linux/ipv6.h>
+#include <uapi/linux/bpf.h>
+#include "ila.h"
+#include "inet_helper.h"
+#include "bpf_helpers.h"
+
+char _license[] SEC("license") = "GPL";
+unsigned int version SEC("version") = 1;
+
+struct bpf_map_def SEC("maps") ila_lookup_map = {
+	.type = BPF_MAP_TYPE_HASH,
+	.key_size = sizeof(struct in6_addr),
+	.value_size = sizeof(struct in6_addr),
+	.max_entries = MAP_SIZE,
+};
+
+#define IPV6_DEST_OFF (ETH_HLEN + offsetof(struct ipv6hdr, daddr))
+
+struct addr {
+	__u64 addr_hi;
+	__u64 addr_lo;
+} __packed;
+
+SEC("classifier")
+int ila_lookup(struct __sk_buff *skb)
+{
+	unsigned long dataptr = (unsigned long)skb->data;
+	struct ethhdr *eth;
+	struct ipv6hdr *sir;
+	struct addr *pkt_addr;
+	struct addr stack_addr;
+	struct addr *reply;
+#ifdef DEBUG
+	char lookup_request[] = "Lookup request for sir: %llx, iden: %llx\n";
+	char lookup_fail[] = "Lookup failed\n";
+	char lookup_success[] = "Lookup success. hi: %llx, lo: %llx\n";
+#endif
+
+	/* Invalid packet: length too short
+	 * compiler optimization/verifier bypass: this way it won't assume
+	 * that we copied over a pkt_ptr,
+	 * which has register range of 0 (from (r1 + 0))
+	 */
+	if (dataptr + sizeof(struct ethhdr) +
+	    sizeof(struct ipv6hdr) > skb->data_end)
+		goto redirect;
+
+	/* Ethernet header */
+	eth = (struct ethhdr *)dataptr;
+
+	/* Irrelevant packet: not IPv6 */
+	if (eth->h_proto != htons(ETH_P_IPV6))
+		goto redirect;
+
+	/* SIR Address header */
+	sir = (struct ipv6hdr *)(dataptr + sizeof(struct ethhdr));
+#ifdef DEBUG
+	{
+		/* ILA Address header */
+		struct ilahdr *ila = (struct ilahdr *)sir;
+
+		/* For debugging purposes,
+		 * we don't care about non-SIR/ILA addresses
+		 */
+		if (ila->destination_address.c)
+			goto redirect;
+
+		switch (ila->destination_address.type) {
+		case SIR_T_LOCAL:
+		case SIR_T_VIRTUAL:
+			break;
+		default:
+			goto redirect;
+		}
+	}
+#endif
+
+	pkt_addr = (struct addr *)&(sir->daddr);
+
+	stack_addr.addr_hi = pkt_addr->addr_hi;
+	stack_addr.addr_lo = pkt_addr->addr_lo;
+
+	reply = bpf_map_lookup_elem(&ila_lookup_map, &stack_addr);
+	if (!reply) {
+#ifdef DEBUG
+		/* Comment out if too noisy */
+		bpf_trace_printk(lookup_request, sizeof(lookup_request),
+				 _ntohll(pkt_addr->addr_hi),
+				 _ntohll(pkt_addr->addr_lo));
+
+		bpf_trace_printk(lookup_fail, sizeof(lookup_fail));
+#endif
+		goto redirect;
+	}
+
+#ifdef DEBUG
+	bpf_trace_printk(lookup_request, sizeof(lookup_request),
+			 _ntohll(pkt_addr->addr_hi),
+			 _ntohll(pkt_addr->addr_lo));
+
+	bpf_trace_printk(lookup_success, sizeof(lookup_success),
+			 _ntohll(reply->addr_hi), _ntohll(reply->addr_lo));
+#endif
+
+	stack_addr.addr_hi = reply->addr_hi;
+	stack_addr.addr_lo = reply->addr_lo;
+
+	bpf_skb_store_bytes(skb, IPV6_DEST_OFF, &stack_addr,
+			    sizeof(struct in6_addr), 0);
+
+redirect:
+	return bpf_redirect(skb->ifindex, 1);
+}
diff --git a/samples/bpf/inet_helper.h b/samples/bpf/inet_helper.h
new file mode 100644
index 0000000..d5fc281
--- /dev/null
+++ b/samples/bpf/inet_helper.h
@@ -0,0 +1,38 @@
+#ifndef __INET_HELPER_H
+#define __INET_HELPER_H
+
+#include <linux/inet.h>
+
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+#define _htonl(A) __builtin_bswap32(A)
+#elif defined(__BIG_ENDIAN_BITFIELD)
+#define _htonl(A) (A)
+#else
+#error "Fix asm/byteorder.h"
+#endif
+
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+#define _ntohl(A) __builtin_bswap32(A)
+#elif defined(__BIG_ENDIAN_BITFIELD)
+#define _ntohl(A) (A)
+#else
+#error "Fix asm/byteorder.h"
+#endif
+
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+#define _htonll(A) __builtin_bswap64(A)
+#elif defined(__BIG_ENDIAN_BITFIELD)
+#define _htonll(A) (A)
+#else
+#error "Fix asm/byteorder.h"
+#endif
+
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+#define _ntohll(A) __builtin_bswap64(A)
+#elif defined(__BIG_ENDIAN_BITFIELD)
+#define _ntohll(A) (A)
+#else
+#error "Fix asm/byteorder.h"
+#endif
+
+#endif
-- 
2.8.0.rc2

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

* [PATCH RFC 2/2] samples/bpf: ilarouter for xdp
  2016-09-23 17:16 [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp Alexei Starovoitov
  2016-09-23 17:16 ` [PATCH RFC 1/2] samples/bpf: ilarouter for tc Alexei Starovoitov
@ 2016-09-23 17:16 ` Alexei Starovoitov
  2016-09-23 18:06 ` [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp Jesper Dangaard Brouer
  2 siblings, 0 replies; 4+ messages in thread
From: Alexei Starovoitov @ 2016-09-23 17:16 UTC (permalink / raw)
  To: David S . Miller
  Cc: Daniel Borkmann, Jesper Dangaard Brouer, Tom Herbert,
	Jamal Hadi Salim, Thomas Graf, netdev

From: Aaron Yue <haoxuany@andrew.cmu.edu>

From: Aaron Yue <haoxuany@fb.com>

Requires a userspace program to insert ila mappings and mac addresses to
the ila map. Needs a verifier patch to directly allow access to the pkt
from the bpf map.

Signed-off-by: Aaron Yue <haoxuany@fb.com>
Signed-off-by: Aaron Yue <haoxuany@andrew.cmu.edu>
---
 samples/bpf/Makefile        |  1 +
 samples/bpf/ilarouter_xdp.c | 88 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 samples/bpf/ilarouter_xdp.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 15e19bb..827e6e8 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -75,6 +75,7 @@ always += test_cgrp2_tc_kern.o
 always += xdp1_kern.o
 always += xdp2_kern.o
 always += ilarouter_tc.o
+always += ilarouter_xdp.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
diff --git a/samples/bpf/ilarouter_xdp.c b/samples/bpf/ilarouter_xdp.c
new file mode 100644
index 0000000..24749c4
--- /dev/null
+++ b/samples/bpf/ilarouter_xdp.c
@@ -0,0 +1,88 @@
+/* Copyright (c) 2016 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#define MAP_SIZE (1 << 20)
+
+#define KBUILD_MODNAME "ilarouter"
+#include <uapi/linux/if_ether.h>
+#include <uapi/linux/ipv6.h>
+#include <uapi/linux/bpf.h>
+#include "bpf_helpers.h"
+
+struct ila_addr {
+	u64 addr_hi;
+	u64 addr_lo;
+} __packed;
+
+struct ila_info {
+	struct ila_addr addr;
+	u16 mac[3];
+} __packed;
+
+char _license[] SEC("license") = "GPL";
+unsigned int version SEC("version") = 1;
+
+struct bpf_map_def SEC("map_ila_lookup_map") ila_lookup_map = {
+	.type = BPF_MAP_TYPE_HASH,
+	.key_size = sizeof(struct in6_addr),
+	.value_size = sizeof(struct ila_info),
+	.max_entries = MAP_SIZE,
+};
+
+SEC("xdp_ila_lookup")
+int ila_lookup(struct xdp_md *ctx)
+{
+	unsigned long dataptr = (unsigned long)ctx->data;
+	struct ethhdr *eth;
+	struct ipv6hdr *sir;
+	struct ila_addr *pkt_addr;
+	struct ila_info *reply;
+	u16 *dst_mac;
+
+	/* Invalid packet: length too short
+	 * compiler optimization/verifier bypass:
+	 * this way it won't assume that we copied over a pkt_ptr,
+	 * which has register range of 0 (from (r1 + 0))
+	 */
+	if (dataptr + sizeof(struct ethhdr) + sizeof(struct ipv6hdr) >
+	    (unsigned long)ctx->data_end)
+		return XDP_PASS;
+
+	/* Ethernet header */
+	eth = (struct ethhdr *)dataptr;
+
+	/* Irrelevant packet: not IPv6 */
+	if (eth->h_proto != htons(ETH_P_IPV6))
+		return XDP_PASS;
+
+	/* Sir Address header */
+	sir = (struct ipv6hdr *)(dataptr + sizeof(struct ethhdr));
+
+	/* We don't have to check for C bit or Type, since
+	 * userspace mapping inserts guarantees that only valid values
+	 * will be inserted into the map in network byte-order.
+	 * Hence, a lookup fail implies either C bit/Type is invalid,
+	 * or mapping does not exist, in both cases we pass the packet without
+	 * modifications.
+	 */
+	pkt_addr = (struct ila_addr *)&(sir->daddr);
+	reply = bpf_map_lookup_elem(&ila_lookup_map, pkt_addr);
+
+	if (!reply)
+		return XDP_PASS;
+
+	pkt_addr->addr_hi = reply->addr.addr_hi;
+	pkt_addr->addr_lo = reply->addr.addr_lo;
+
+	dst_mac = (u16 *)eth;
+	dst_mac[0] = reply->mac[0];
+	dst_mac[1] = reply->mac[1];
+	dst_mac[2] = reply->mac[2];
+
+	return XDP_TX;
+}
+
-- 
2.8.0.rc2

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

* Re: [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp
  2016-09-23 17:16 [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp Alexei Starovoitov
  2016-09-23 17:16 ` [PATCH RFC 1/2] samples/bpf: ilarouter for tc Alexei Starovoitov
  2016-09-23 17:16 ` [PATCH RFC 2/2] samples/bpf: ilarouter for xdp Alexei Starovoitov
@ 2016-09-23 18:06 ` Jesper Dangaard Brouer
  2 siblings, 0 replies; 4+ messages in thread
From: Jesper Dangaard Brouer @ 2016-09-23 18:06 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David S . Miller, Daniel Borkmann, Tom Herbert, Jamal Hadi Salim,
	Thomas Graf, netdev, brouer


On Fri, 23 Sep 2016 10:16:33 -0700 Alexei Starovoitov <ast@fb.com> wrote:

> From: Aaron Yue <haoxuany@andrew.cmu.edu>
> 
> Jesper,
> 
> here is old email and cover letter that didn't make it to the list
> due to vger outage (I guess).
> The verifier patch that Aaron is talking about has landed long ago.
> 
> The dataplane of ILA router is very short and simple.

Yes, looks very simple indeed! Cool! :-)


> Control plane is very different matter. It's not ready for prime time yet.
> 
> ----------
> 
> This patch contains the tc and xdp implementation of kernelspace bpf code.
> It requires userspace to insert to the ILA bpf maps, in tc's case, the 
> precomputed ILA mappings, and in xdp's case, both the precomputed ILA
> mappings and the MAC address.
> 
> The xdp bpf code also requires a verifier patch to allow direct map access
> from the packet (will be patched in by Alexei).
> 
> Aaron Yue (2):
>   samples/bpf: ilarouter for tc
>   samples/bpf: ilarouter for xdp
> 
>  samples/bpf/Makefile        |   2 +
>  samples/bpf/ila.h           |  80 ++++++++++++++++++++++++++++
>  samples/bpf/ilarouter_tc.c  | 124 ++++++++++++++++++++++++++++++++++++++++++++
>  samples/bpf/ilarouter_xdp.c |  88 +++++++++++++++++++++++++++++++
>  samples/bpf/inet_helper.h   |  38 ++++++++++++++
>  5 files changed, 332 insertions(+)
>  create mode 100644 samples/bpf/ila.h
>  create mode 100644 samples/bpf/ilarouter_tc.c
>  create mode 100644 samples/bpf/ilarouter_xdp.c
>  create mode 100644 samples/bpf/inet_helper.h

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  Author of http://www.iptv-analyzer.org
  LinkedIn: http://www.linkedin.com/in/brouer

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

end of thread, other threads:[~2016-09-23 18:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-23 17:16 [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp Alexei Starovoitov
2016-09-23 17:16 ` [PATCH RFC 1/2] samples/bpf: ilarouter for tc Alexei Starovoitov
2016-09-23 17:16 ` [PATCH RFC 2/2] samples/bpf: ilarouter for xdp Alexei Starovoitov
2016-09-23 18:06 ` [PATCH RFC 0/2] ila: ilarouter bpf code for tc and xdp Jesper Dangaard Brouer

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).