// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "portier/nd_bpf.h"

#include <limits.h>
#include <linux/filter.h>
#include <net/ethernet.h>
#include <netinet/icmp6.h>
#include <netinet/ip6.h>
#include <stddef.h>

namespace portier {

namespace {

// Outgoing hop-limit of proxied IPv6 packets.  Required by RFC 4389 to
// prevent receivers from dropping what may appear to be forwarded packets.
constexpr uint8_t kProxiedHopLimit = 255;

// This constant is used by BPF programs to indicate that the entire packet
// should be returned to user-space.
constexpr uint32_t kEntirePacket = INT_MAX;

// BPF notes:
//   BPF_STMT(code, k)
//   BPF_JUMP(code, k, j true, j false)
//
// The return value of a BPF program is the number of bytes of the packet
// that should be passed to the user-space program.  Zero is a special
// value in that the packet is simply dropped, and the user-space socket
// is never notified of the packet.  Returning a number larger than the
// actaul length of the packet will cause the entire packet to be passed
// to the user-space program.
//
// Any out of bounds exceptions, illegal OPs code, divide by zero, and other
// possible errors cause the BPF program to exit as if it had returned zero.
// This is a desired feature as the BPF program can be made to assume the
// whole packet is received without doing any bound checks.  If the packet
// was corrupted or truncated during transit, then the BPF will drop it
// when accessing out of bound data.

// BPF for ICMPv6 Neighbor Solicitation.
// Algorithm:
//  ether_header = packet_buf;  // Start of frame.
//  if (ether_header->ether_type != IPv6) {
//    return 0;
//  }
//  ip6_hdr = ether_header + sizeof(struct ether_header);  // IPv6 header
//  if (ip6_hdr->ip6_nxt != ICMPv6 || ip6_hdr->ip6_hops != 255) {
//    return 0;
//  }
//  icmp6_hdr = ip6_hdr + sizeof(struct ip6_hdr);  // ICMPv6 header
//  if (icmp6_hdr->icmp6_type != NS &&
//      icmp6_hdr->icmp6_type != NA &&
//      icmp6_hdr->icmp6_type != RA &&
//      icmp6_hdr->icmp6_type != R) {
//    return 0;
//  }
//  if (icmp6_hdr->icmp6_code != 0) {
//    return 0;
//  }
//  return MAX;
struct sock_filter kNeighborDiscoveryFilterInstructions[] = {
    // Load ethernet type (16-bits, H).
    BPF_STMT(BPF_LD | BPF_H | BPF_ABS,
             offsetof(struct ether_header, ether_type)),
    // Check if it equals IPv6, skip next if true.
    BPF_JUMP(BPF_JMP | BPF_JEQ, ETHERTYPE_IPV6, 1, 0),
    // Return 0.
    BPF_STMT(BPF_RET | BPF_K, 0),
    // Move index to start of IPv6 header.
    BPF_STMT(BPF_LDX | BPF_IMM, sizeof(struct ether_header)),
    // Load IPv6 next header (8-bits, B).
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(struct ip6_hdr, ip6_nxt)),
    // Check if equals ICMPv6, if not, then goto return 0.
    BPF_JUMP(BPF_JMP | BPF_JEQ, IPPROTO_ICMPV6, 0, 2),
    // Load IPv6 hop limit (8-bit, B).
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(struct ip6_hdr, ip6_hops)),
    // Check if equal to 255, skip return if true.
    BPF_JUMP(BPF_JMP | BPF_JEQ, kProxiedHopLimit, 1, 0),
    // Return 0.
    BPF_STMT(BPF_RET | BPF_K, 0),
    // Move index to start of ICMPv6 header.
    BPF_STMT(BPF_MISC | BPF_TXA, 0),
    BPF_STMT(BPF_ALU | BPF_ADD | BPF_IMM, sizeof(struct ip6_hdr)),
    BPF_STMT(BPF_MISC | BPF_TAX, 0),
    // Load ICMPv6 type (8-bits, B).
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(struct icmp6_hdr, icmp6_type)),
    // Check if is ND ICMPv6 message.
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_ROUTER_ADVERT, 4, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_NEIGHBOR_SOLICIT, 3, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_NEIGHBOR_ADVERT, 2, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_REDIRECT, 1, 0),
    // Return 0.
    BPF_STMT(BPF_RET | BPF_K, 0),
    // Load ICMPv6 code (8-bit, B).
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(struct icmp6_hdr, icmp6_code)),
    // Check if is code 0.
    BPF_JUMP(BPF_JMP | BPF_JEQ, 0, 1, 0),
    // Return 0.
    BPF_STMT(BPF_RET | BPF_K, 0),
    // Return MAX.
    BPF_STMT(BPF_RET | BPF_K, kEntirePacket),
};

// BPF for IPv6 packets, other than ICMPv6 Neighbor Discovery.
// Algorithm is the similar to ND Filter above, except that it returns
// max if the IPv6 packet is not a one of the ND Messages that require
// special proxying rules.
struct sock_filter kNonNDFilterInstructions[] = {
    // Load ethernet type (16-bits, H).
    BPF_STMT(BPF_LD | BPF_H | BPF_ABS,
             offsetof(struct ether_header, ether_type)),
    // Check if it equals IPv6, skip next if true.
    BPF_JUMP(BPF_JMP | BPF_JEQ, ETHERTYPE_IPV6, 1, 0),
    // Return 0.
    BPF_STMT(BPF_RET | BPF_K, 0),
    // Move index to start of IPv6 header.
    BPF_STMT(BPF_LDX | BPF_IMM, sizeof(struct ether_header)),
    // Load IPv6 next header (8-bits, B).
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(struct ip6_hdr, ip6_nxt)),
    // Check if equals ICMPv6, if not, then return max.
    BPF_JUMP(BPF_JMP | BPF_JEQ, IPPROTO_ICMPV6, 1, 0),
    // Return MAX.
    BPF_STMT(BPF_RET | BPF_K, kEntirePacket),
    // Move index to start of ICMPv6 header.
    BPF_STMT(BPF_MISC | BPF_TXA, 0),
    BPF_STMT(BPF_ALU | BPF_ADD | BPF_IMM, sizeof(struct ip6_hdr)),
    BPF_STMT(BPF_MISC | BPF_TAX, 0),
    // Load ICMPv6 type (8-bits, B).
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(struct icmp6_hdr, icmp6_type)),
    // Check if is ND ICMPv6 message.
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_ROUTER_ADVERT, 4, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_NEIGHBOR_SOLICIT, 3, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_NEIGHBOR_ADVERT, 2, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ, ND_REDIRECT, 1, 0),
    // Return MAX.
    BPF_STMT(BPF_RET | BPF_K, kEntirePacket),
    // Return 0.
    BPF_STMT(BPF_RET | BPF_K, 0),
};

}  // namespace

const struct sock_fprog kNeighborDiscoveryFilter = {
    sizeof(kNeighborDiscoveryFilterInstructions) / sizeof(struct sock_filter),
    kNeighborDiscoveryFilterInstructions};

const struct sock_fprog kNonNeighborDiscoveryFilter = {
    sizeof(kNonNDFilterInstructions) / sizeof(struct sock_filter),
    kNonNDFilterInstructions};

}  // namespace portier.
