cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xdp2_kern.c (2488B)


      1/* Copyright (c) 2016 PLUMgrid
      2 *
      3 * This program is free software; you can redistribute it and/or
      4 * modify it under the terms of version 2 of the GNU General Public
      5 * License as published by the Free Software Foundation.
      6 */
      7#define KBUILD_MODNAME "foo"
      8#include <uapi/linux/bpf.h>
      9#include <linux/in.h>
     10#include <linux/if_ether.h>
     11#include <linux/if_packet.h>
     12#include <linux/if_vlan.h>
     13#include <linux/ip.h>
     14#include <linux/ipv6.h>
     15#include <bpf/bpf_helpers.h>
     16
     17struct {
     18	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
     19	__type(key, u32);
     20	__type(value, long);
     21	__uint(max_entries, 256);
     22} rxcnt SEC(".maps");
     23
     24static void swap_src_dst_mac(void *data)
     25{
     26	unsigned short *p = data;
     27	unsigned short dst[3];
     28
     29	dst[0] = p[0];
     30	dst[1] = p[1];
     31	dst[2] = p[2];
     32	p[0] = p[3];
     33	p[1] = p[4];
     34	p[2] = p[5];
     35	p[3] = dst[0];
     36	p[4] = dst[1];
     37	p[5] = dst[2];
     38}
     39
     40static int parse_ipv4(void *data, u64 nh_off, void *data_end)
     41{
     42	struct iphdr *iph = data + nh_off;
     43
     44	if (iph + 1 > data_end)
     45		return 0;
     46	return iph->protocol;
     47}
     48
     49static int parse_ipv6(void *data, u64 nh_off, void *data_end)
     50{
     51	struct ipv6hdr *ip6h = data + nh_off;
     52
     53	if (ip6h + 1 > data_end)
     54		return 0;
     55	return ip6h->nexthdr;
     56}
     57
     58SEC("xdp1")
     59int xdp_prog1(struct xdp_md *ctx)
     60{
     61	void *data_end = (void *)(long)ctx->data_end;
     62	void *data = (void *)(long)ctx->data;
     63	struct ethhdr *eth = data;
     64	int rc = XDP_DROP;
     65	long *value;
     66	u16 h_proto;
     67	u64 nh_off;
     68	u32 ipproto;
     69
     70	nh_off = sizeof(*eth);
     71	if (data + nh_off > data_end)
     72		return rc;
     73
     74	h_proto = eth->h_proto;
     75
     76	/* Handle VLAN tagged packet */
     77	if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
     78		struct vlan_hdr *vhdr;
     79
     80		vhdr = data + nh_off;
     81		nh_off += sizeof(struct vlan_hdr);
     82		if (data + nh_off > data_end)
     83			return rc;
     84		h_proto = vhdr->h_vlan_encapsulated_proto;
     85	}
     86	/* Handle double VLAN tagged packet */
     87	if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
     88		struct vlan_hdr *vhdr;
     89
     90		vhdr = data + nh_off;
     91		nh_off += sizeof(struct vlan_hdr);
     92		if (data + nh_off > data_end)
     93			return rc;
     94		h_proto = vhdr->h_vlan_encapsulated_proto;
     95	}
     96
     97	if (h_proto == htons(ETH_P_IP))
     98		ipproto = parse_ipv4(data, nh_off, data_end);
     99	else if (h_proto == htons(ETH_P_IPV6))
    100		ipproto = parse_ipv6(data, nh_off, data_end);
    101	else
    102		ipproto = 0;
    103
    104	value = bpf_map_lookup_elem(&rxcnt, &ipproto);
    105	if (value)
    106		*value += 1;
    107
    108	if (ipproto == IPPROTO_UDP) {
    109		swap_src_dst_mac(data);
    110		rc = XDP_TX;
    111	}
    112
    113	return rc;
    114}
    115
    116char _license[] SEC("license") = "GPL";