Skip to content

Commit

Permalink
Snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
YutaroHayakawa committed May 16, 2018
1 parent efe40ce commit 36b296c
Show file tree
Hide file tree
Showing 11 changed files with 519 additions and 300 deletions.
14 changes: 14 additions & 0 deletions apps/learning_bridge/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CFLAGS = \
-I ../../sys \

all: learning_bridge.o learning_bridge_loader

learning_bridge.bpf.o: learning_bridge.bpf.c
clang38 $(CFLAGS) -O3 -target bpf -c learning_bridge.bpf.c

learning_bridge_loader: learning_bridge.o learning_bridge_loader.c
$(CC) $(CFLAGS) -O0 -g -o $@ learning_bridge_loader.c -lgbpf -lelf


clean:
- rm learning_bridge.bpf.o
62 changes: 62 additions & 0 deletions apps/learning_bridge/learning_bridge.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*-
* SPDX-License-Identifier: Apache License 2.0
*
* Copyright 2017-2018 Yutaro Hayakawa
*
* 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.
*/

#include <stdint.h>
#include <sys/ebpf_uapi.h>
#include <net/vale_bpf_uapi.h>

DEFINE_MAP(ft, HASHTABLE, sizeof(uint64_t), sizeof(uint32_t), 256, 0);

// Assume little endian
#define le64toh(x) __builtin_bswap64(x)

uint32_t
learning_bridge(struct vale_bpf_md *md)
{
int error;
uint8_t *data = (uint8_t *)md->data;
uint8_t *data_end = (uint8_t *)md->data_end;

if (md->data_end - md->data < 14) {
return VALE_BPF_DROP;
}

uint64_t smac, dmac;
dmac = le64toh(*(uint64_t *)(data)) & 0xffffffffffff;
smac = le64toh(*(uint64_t *)(data + 4));
smac >>= 16;

if (((data[6] & 1) == 0)) {
error = map_update_elem(&ft, data + 6, &md->ingress_port, EBPF_ANY);
if (error) {
return VALE_BPF_DROP;
}
}

uint32_t *dport;
if ((data[0] & 1) == 0) {
dport = map_lookup_elem(&ft, &dmac, 0);
if (!dport) {
return VALE_BPF_DROP;
}

return *dport;
}

return VALE_BPF_BROADCAST;
}
92 changes: 92 additions & 0 deletions apps/learning_bridge/learning_bridge_loader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*-
* SPDX-License-Identifier: Apache License 2.0
*
* Copyright 2017-2018 Yutaro Hayakawa
*
* 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.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <net/if.h>
#include <sys/ioctl.h>

#include <sys/ebpf.h>
#include <sys/ebpf_uapi.h>
#include <sys/ebpf_inst.h>
#include <sys/ebpf_dev.h>
#include <net/vale_bpf.h>
#include <gbpf/gbpf.h>

#include "../utils/vale_bpf_elf_loader.h"

static int end = 0;

static void
on_sigint(int sig)
{
end = 1;
}

int
main(void)
{
int nmfd, error;

nmfd = open("/dev/netmap", O_RDWR);
if (nmfd < 0) {
perror("open /dev/netmap");
exit(EXIT_FAILURE);
}

struct vale_bpf_info *info;
info = vale_bpf_load_elf("./learning_bridge.bpf.o");
if (!info) {
printf("Failed to load leaning_bridge.o\n");
exit(EXIT_FAILURE);
}

if (info->progs[0].fd == 0) {
printf("There is no program in learning_bridge.o\n");
exit(EXIT_FAILURE);
}

error = vale_bpf_load_prog(nmfd, "vale0:", info->progs[0].fd);
if (error) {
printf("Failed to load program to vale0\n");
exit(EXIT_FAILURE);
}

signal(SIGINT, on_sigint);

printf("Running learning bridge on vale0, press Ctrl-C to finish\n");
while (!end) {
sleep(1);
}

error = vale_bpf_unload_prog(nmfd, "vale0:");
if (error) {
printf("Failed to unload program from vale0\n");
exit(EXIT_FAILURE);
}

free(info);
close(nmfd);

return EXIT_SUCCESS;
}
130 changes: 130 additions & 0 deletions apps/utils/vale_bpf_elf_loader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*-
* SPDX-License-Identifier: Apache License 2.0
*
* Copyright 2017-2018 Yutaro Hayakawa
*
* 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.
*/

#pragma once

struct map_entry {
char name[256];
int fd;
};

struct prog_entry {
char name[256];
struct ebpf_inst *prog;
uint32_t prog_len;
int fd;
};

#define NPROG_MAX 1
#define NMAP_MAX 256

struct vale_bpf_info {
uint32_t nprog;
uint32_t nmap;
struct prog_entry progs[NPROG_MAX];
struct map_entry maps[NPROG_MAX];
};

static void
on_prog(GBPFElfWalker *walker, const char *name,
struct ebpf_inst *prog, uint32_t prog_len)
{
struct vale_bpf_info *info = walker->data;

if (info->nprog == NPROG_MAX) {
printf("Error: Too many programs\n");
return;
}

if (strlen(name) > 255) {
printf("Error: Prog name is too long\n");
return;
}

strcpy(info->progs[info->nprog].name, name);
info->progs[info->nprog].prog = prog;
info->progs[info->nprog].prog_len = prog_len;
info->nprog++;
}

static void
on_map(GBPFElfWalker *walker, const char *name,
int desc, struct ebpf_map_def *map)
{
struct vale_bpf_info *info = walker->data;

if (info->nmap == NMAP_MAX) {
printf("Error: Too many maps\n");
return;
}

if (strlen(name) > 255) {
printf("Error: Map name is too long\n");
return;
}

strcpy(info->maps[info->nmap].name, name);
info->maps[info->nmap].fd = desc;
info->nmap++;
}

static struct vale_bpf_info *
vale_bpf_load_elf(char *elf_fname)
{
int error, nmfd, prog_fd;
EBPFDevDriver *driver;
GBPFElfWalker walker;
struct vale_bpf_info *ret;

ret = malloc(sizeof(struct vale_bpf_info));
if (!ret) {
return NULL;
}
memset(ret, 0, sizeof(struct vale_bpf_info));

driver = ebpf_dev_driver_create();
if (!driver) {
free(ret);
return NULL;
}

walker.on_prog = on_prog;
walker.on_map = on_map;
walker.data = ret;

error = gbpf_walk_elf(&walker, (GBPFDriver *)driver, elf_fname);
if (error) {
free(ret);
ebpf_dev_driver_destroy(driver);
return NULL;
}

// Currently only handles one program
prog_fd = gbpf_load_prog((GBPFDriver *)driver, EBPF_PROG_TYPE_TEST,
ret->progs[0].prog, ret->progs[0].prog_len);
if (prog_fd < 0) {
free(ret);
ebpf_dev_driver_destroy(driver);
return NULL;
}
ret->progs[0].fd = prog_fd;

ebpf_dev_driver_destroy(driver);

return ret;
}
7 changes: 0 additions & 7 deletions apps/vale-bpf/Makefile

This file was deleted.

Loading

0 comments on commit 36b296c

Please sign in to comment.