-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
efe40ce
commit 36b296c
Showing
11 changed files
with
519 additions
and
300 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.