Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
[sfrench/cifs-2.6.git] / samples / bpf / xdp_fwd_kern.c
index a7e94e7ff87df5f60f7a57522de77b5929e46029..701a30f258b17d34f804ec358db976b8175511f5 100644 (file)
@@ -23,7 +23,8 @@
 
 #define IPV6_FLOWINFO_MASK              cpu_to_be32(0x0FFFFFFF)
 
-struct bpf_map_def SEC("maps") tx_port = {
+/* For TX-traffic redirect requires net_device ifindex to be in this devmap */
+struct bpf_map_def SEC("maps") xdp_tx_ports = {
        .type = BPF_MAP_TYPE_DEVMAP,
        .key_size = sizeof(int),
        .value_size = sizeof(int),
@@ -102,14 +103,34 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
        fib_params.ifindex = ctx->ingress_ifindex;
 
        rc = bpf_fib_lookup(ctx, &fib_params, sizeof(fib_params), flags);
-
-       /* verify egress index has xdp support
-        * TO-DO bpf_map_lookup_elem(&tx_port, &key) fails with
-        *       cannot pass map_type 14 into func bpf_map_lookup_elem#1:
-        * NOTE: without verification that egress index supports XDP
-        *       forwarding packets are dropped.
+       /*
+        * Some rc (return codes) from bpf_fib_lookup() are important,
+        * to understand how this XDP-prog interacts with network stack.
+        *
+        * BPF_FIB_LKUP_RET_NO_NEIGH:
+        *  Even if route lookup was a success, then the MAC-addresses are also
+        *  needed.  This is obtained from arp/neighbour table, but if table is
+        *  (still) empty then BPF_FIB_LKUP_RET_NO_NEIGH is returned.  To avoid
+        *  doing ARP lookup directly from XDP, then send packet to normal
+        *  network stack via XDP_PASS and expect it will do ARP resolution.
+        *
+        * BPF_FIB_LKUP_RET_FWD_DISABLED:
+        *  The bpf_fib_lookup respect sysctl net.ipv{4,6}.conf.all.forwarding
+        *  setting, and will return BPF_FIB_LKUP_RET_FWD_DISABLED if not
+        *  enabled this on ingress device.
         */
-       if (rc == 0) {
+       if (rc == BPF_FIB_LKUP_RET_SUCCESS) {
+               /* Verify egress index has been configured as TX-port.
+                * (Note: User can still have inserted an egress ifindex that
+                * doesn't support XDP xmit, which will result in packet drops).
+                *
+                * Note: lookup in devmap supported since 0cdbb4b09a0.
+                * If not supported will fail with:
+                *  cannot pass map_type 14 into func bpf_map_lookup_elem#1:
+                */
+               if (!bpf_map_lookup_elem(&xdp_tx_ports, &fib_params.ifindex))
+                       return XDP_PASS;
+
                if (h_proto == htons(ETH_P_IP))
                        ip_decrease_ttl(iph);
                else if (h_proto == htons(ETH_P_IPV6))
@@ -117,7 +138,7 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
 
                memcpy(eth->h_dest, fib_params.dmac, ETH_ALEN);
                memcpy(eth->h_source, fib_params.smac, ETH_ALEN);
-               return bpf_redirect_map(&tx_port, fib_params.ifindex, 0);
+               return bpf_redirect_map(&xdp_tx_ports, fib_params.ifindex, 0);
        }
 
        return XDP_PASS;