summaryrefslogtreecommitdiffstats
path: root/extras/bpf/af_xdp.bpf.c
diff options
context:
space:
mode:
@media only all and (prefers-color-scheme: dark) { .highlight .hll { background-color: #49483e } .highlight .c { color: #75715e } /* Comment */ .highlight .err { color: #960050; background-color: #1e0010 } /* Error */ .highlight .k { color: #66d9ef } /* Keyword */ .highlight .l { color: #ae81ff } /* Literal */ .highlight .n { color: #f8f8f2 } /* Name */ .highlight .o { color: #f92672 } /* Operator */ .highlight .p { color: #f8f8f2 } /* Punctuation */ .highlight .ch { color: #75715e } /* Comment.Hashbang */ .highlight .cm { color: #75715e } /* Comment.Multiline */ .highlight .cp { color: #75715e } /* Comment.Preproc */ .highlight .cpf { color: #75715e } /* Comment.PreprocFile */ .highlight .c1 { color: #75715e } /* Comment.Single */ .highlight .cs { color: #75715e } /* Comment.Special */ .highlight .gd { color: #f92672 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gi { color: #a6e22e } /* Generic.Inserted */ .highlight .gs { font-weig
Diffstat (limited to 'extras/bpf/af_xdp.bpf.c')
authorBenoƮt Ganne <bganne@cisco.com>2020-06-12 08:47:34 +0200
committerDamjan Marion <dmarion@me.com>2020-08-31 17:16:56 +0000
commit4a76d6f6da035220917097bc047b08bc58254803 (patch)
-rw-r--r--extras/bpf/af_xdp.bpf.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/extras/bpf/af_xdp.bpf.c b/extras/bpf/af_xdp.bpf.c
new file mode 100644
index 00000000000..eddd2b0e509
--- /dev/null
+++ b/extras/bpf/af_xdp.bpf.c
@@ -0,0 +1,88 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
+ * Dual-licensed under GPL version 2.0 or Apache License version 2.0
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ */
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <bpf/bpf_helpers.h>
+
+/*
+ * when compiled, debug print can be viewed with eg.
+ * sudo cat /sys/kernel/debug/tracing/trace_pipe
+ */
+#ifdef DEBUG
+#define s__(n) # n
+#define s_(n) s__(n)
+#define x_(fmt) __FILE__ ":" s_(__LINE__) ": " fmt "\n"
+#define DEBUG_PRINT_(fmt, ...) do { \
+ const char fmt__[] = fmt; \
+ bpf_trace_printk(fmt__, sizeof(fmt), ## __VA_ARGS__); } while(0)
+#define DEBUG_PRINT(fmt, ...) DEBUG_PRINT_ (x_(fmt), ## __VA_ARGS__)
+#else /* DEBUG */
+#define DEBUG_PRINT(fmt, ...)
+#endif /* DEBUG */
+
+#define ntohs(x) __constant_ntohs(x)
+
+SEC("maps")
+struct bpf_map_def xsks_map = {
+ .type = BPF_MAP_TYPE_XSKMAP,
+ .key_size = sizeof(int),
+ .value_size = sizeof(int),
+ .max_entries = 64, /* max 64 queues per device */
+};
+
+SEC("xdp_sock")
+int xdp_sock_prog(struct xdp_md *ctx) {
+ const void *data = (void *)(long)ctx->data;
+ const void *data_end = (void *)(long)ctx->data_end;
+
+ DEBUG_PRINT("rx %ld bytes packet", (long)data_end - (long)data);
+
+ /* smallest packet we are interesting in is ip-ip */
+ if (data + sizeof(struct ethhdr) + 2 * sizeof(struct iphdr) > data_end) {
+ DEBUG_PRINT("packet too small");
+ return XDP_PASS;
+ }
+
+ const struct ethhdr *eth = data;
+ if (eth->h_proto != ntohs(ETH_P_IP)) {
+ DEBUG_PRINT("unsupported eth proto %x", (int)eth->h_proto);
+ return XDP_PASS;
+ }
+
+ const struct iphdr *ip = (void *)(eth + 1);
+ switch (ip->protocol) {
+ case IPPROTO_UDP: {
+ const struct udphdr *udp = (void *)(ip + 1);
+ if (udp->dest != ntohs(4789)) { /* VxLAN dest port */
+ DEBUG_PRINT("unsupported udp dst port %x", (int)udp->dest);
+ return XDP_PASS;
+ }
+ }
+ case IPPROTO_IPIP:
+ case IPPROTO_ESP:
+ break;
+ default:
+ DEBUG_PRINT("unsupported ip proto %x", (int)ip->protocol);
+ return XDP_PASS;
+ }
+
+ int qid = ctx->rx_queue_index;
+ if (!bpf_map_lookup_elem(&xsks_map, &qid))
+ {
+ DEBUG_PRINT("no socket found");
+ return XDP_PASS;
+ }
+
+ DEBUG_PRINT("going to socket %d", qid);
+ return bpf_redirect_map(&xsks_map, qid, 0);
+}
+
+/* actually Dual GPLv2/Apache2, but GPLv2 as far as kernel is concerned */
+SEC("license")
+char _license[] = "GPL";
iteral.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * l2_learn.c : layer 2 learning using l2fib
 *
 * Copyright (c) 2014 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef included_l2learn_h
#define included_l2learn_h

#include <vlib/vlib.h>
#include <vnet/ethernet/ethernet.h>


typedef struct
{

  /* Hash table */
  BVT (clib_bihash) * mac_table;

  /* number of dynamically learned mac entries */
  u32 global_learn_count;

  /* maximum number of dynamically learned mac entries */
  u32 global_learn_limit;

  /* client waiting for L2 MAC events for learned and aged MACs */
  u32 client_pid;
  u32 client_index;

  /* Next nodes for each feature */
  u32 feat_next_node_index[32];

  /* convenience variables */
  vlib_main_t *vlib_main;
  vnet_main_t *vnet_main;
} l2learn_main_t;

#define L2LEARN_DEFAULT_LIMIT (L2FIB_NUM_BUCKETS * 64)

extern l2learn_main_t l2learn_main;

extern vlib_node_registration_t l2fib_mac_age_scanner_process_node;

enum
{
  L2_MAC_AGE_PROCESS_EVENT_START = 1,
  L2_MAC_AGE_PROCESS_EVENT_STOP = 2,
  L2_MAC_AGE_PROCESS_EVENT_ONE_PASS = 3,
} l2_mac_age_process_event_t;

#endif

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */