Skip to content

Commit

Permalink
common
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaozhangchannel committed Jun 3, 2024
1 parent 8c29531 commit eb8a0da
Show file tree
Hide file tree
Showing 16 changed files with 1,496 additions and 0 deletions.
18 changes: 18 additions & 0 deletions eBPF_Supermarket/Network_Subsystem/net_manager/common/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: (GPL-2.0)
LIB_DIR = ../lib
include $(LIB_DIR)/defines.mk

all: common_params.o common_user_bpf_xdp.o

CFLAGS += -I$(LIB_DIR)/install/include

common_params.o: common_params.c common_params.h
$(QUIET_CC)$(CC) $(CFLAGS) -c -o $@ $<

common_user_bpf_xdp.o: common_user_bpf_xdp.c common_user_bpf_xdp.h
$(QUIET_CC)$(CC) $(CFLAGS) -c -o $@ $<

.PHONY: clean

clean:
$(Q)rm -f *.o
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# -*- fill-column: 76; -*-
#+TITLE: Common files
#+OPTIONS: ^:nil

This directory contains code that is common between the different
assignments. This reduce code duplication in each tutorial assignment, and
allow us to hideaway code that is irrelevant or have been seen/introduced in
earlier assignments.
128 changes: 128 additions & 0 deletions eBPF_Supermarket/Network_Subsystem/net_manager/common/common.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Common Makefile parts for BPF-building with libbpf
# --------------------------------------------------
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
#
# This file should be included from your Makefile like:
# COMMON_DIR = ../common
# include $(COMMON_DIR)/common.mk
#
# It is expected that you define the variables:
# XDP_TARGETS and USER_TARGETS
# as a space-separated list
#
LLC ?= llc
CLANG ?= clang
CC ?= gcc

XDP_C = ${XDP_TARGETS:=.c}
XDP_OBJ = ${XDP_C:.c=.o}
USER_C := ${USER_TARGETS:=.c}
USER_OBJ := ${USER_C:.c=.o}

# Expect this is defined by including Makefile, but define if not
COMMON_DIR ?= ../common
LIB_DIR ?= ../lib

COPY_LOADER ?=
LOADER_DIR ?= $(LIB_DIR)/xdp-tools/xdp-loader
STATS_DIR ?= $(COMMON_DIR)/../basic-solutions

COMMON_OBJS += $(COMMON_DIR)/common_params.o
include $(LIB_DIR)/defines.mk

# Create expansions for dependencies
COMMON_H := ${COMMON_OBJS:.o=.h}

EXTRA_DEPS +=

XLB_OBJS +=

# BPF-prog kern and userspace shares struct via header file:
KERN_USER_H ?= $(wildcard common_kern_user.h)

CFLAGS += -I$(LIB_DIR)/install/include $(EXTRA_CFLAGS) -g
BPF_CFLAGS += -I$(LIB_DIR)/install/include $(EXTRA_CFLAGS) -g
LDFLAGS += -L$(LIB_DIR)/install/lib

BPF_HEADERS := $(wildcard $(HEADER_DIR)/*/*.h) $(wildcard $(INCLUDE_DIR)/*/*.h)

all: llvm-check $(USER_TARGETS) $(XDP_OBJ) $(COPY_LOADER) $(COPY_STATS)

.PHONY: clean $(CLANG) $(LLC)

clean:
$(Q)rm -f $(USER_TARGETS) $(XDP_OBJ) $(USER_OBJ) $(COPY_LOADER) $(COPY_STATS) *.ll $(XLB_OBJS)

ifdef COPY_LOADER
$(LOADER_DIR)/$(COPY_LOADER):
$(Q)make -C $(LOADER_DIR)

$(COPY_LOADER): $(LOADER_DIR)/$(COPY_LOADER)
$(QUIET_COPY)cp $(LOADER_DIR)/$(COPY_LOADER) $(COPY_LOADER)
endif

ifdef COPY_STATS
$(STATS_DIR)/$(COPY_STATS): $(STATS_DIR)/${COPY_STATS:=.c} $(COMMON_H)
$(Q)make -C $(STATS_DIR) $(COPY_STATS)

$(COPY_STATS): $(STATS_DIR)/$(COPY_STATS)
$(QUIET_COPY)cp $(STATS_DIR)/$(COPY_STATS) $(COPY_STATS)
# Needing xdp_stats imply depending on header files:
EXTRA_DEPS += $(COMMON_DIR)/xdp_stats_kern.h $(COMMON_DIR)/xdp_stats_kern_user.h
endif

# For build dependency on this file, if it gets updated
COMMON_MK = $(COMMON_DIR)/common.mk

llvm-check: $(CLANG) $(LLC)
@for TOOL in $^ ; do \
if [ ! $$(command -v $${TOOL} 2>/dev/null) ]; then \
echo "*** ERROR: Cannot find tool $${TOOL}" ;\
exit 1; \
else true; fi; \
done

$(OBJECT_LIBBPF):
@if [ ! -d $(LIBBPF_DIR) ]; then \
echo "Error: Need libbpf submodule" $(LIBBPF_DIR); \
echo "May need to run git submodule update --init"; \
exit 1; \
else \
cd $(LIBBPF_DIR) && $(MAKE) all OBJDIR=.; \
mkdir -p build; $(MAKE) install_headers DESTDIR=build OBJDIR=.; \
fi

$(OBJECT_LIBXDP):
@if [ ! -d $(LIBXDP_DIR) ]; then \
echo "Error: Need libxdp submodule" $(LIBXDP_DIR); \
echo "May need to run git submodule update --init"; \
exit 1; \
else \
cd $(LIBXDP_DIR) && $(MAKE) all OBJDIR=.; \
fi

# Create dependency: detect if C-file change and touch H-file, to trigger
# target $(COMMON_OBJS)
$(COMMON_H): %.h: %.c
touch $@

# Detect if any of common obj changed and create dependency on .h-files
$(COMMON_OBJS): %.o: %.h
$(Q)$(MAKE) -C $(COMMON_DIR)

$(USER_TARGETS): %: %.c $(OBJECT_LIBBPF) $(OBJECT_LIBXDP) Makefile $(COMMON_MK) $(COMMON_OBJS) $(KERN_USER_H) $(EXTRA_DEPS) $(XLB_OBJS)
$(QUIET_CC)$(CC) -Wall $(CFLAGS) $(LDFLAGS) -o $@ $(COMMON_OBJS) $(XLB_OBJS) $(LIB_OBJS) \
$< $(LDLIBS)

$(XDP_OBJ): %.o: %.c Makefile $(COMMON_MK) $(KERN_USER_H) $(EXTRA_DEPS) $(OBJECT_LIBBPF)
$(QUIET_CLANG)$(CLANG) -S \
-target bpf \
-D __BPF_TRACING__ \
$(BPF_CFLAGS) \
-Wall \
-Wno-unused-value \
-Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Werror \
-O2 -emit-llvm -c -g -o ${@:.o=.ll} $<
$(QUIET_LLC)$(LLC) -march=bpf -filetype=obj -o $@ ${@:.o=.ll}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef __COMMON_DEFINES_H
#define __COMMON_DEFINES_H

#include <net/if.h>
#include <linux/types.h>
#include <stdbool.h>
#include <xdp/libxdp.h>

struct config {
enum xdp_attach_mode attach_mode;
__u32 xdp_flags;
int ifindex;
char *ifname;
char ifname_buf[IF_NAMESIZE];
int redirect_ifindex;
char *redirect_ifname;
char redirect_ifname_buf[IF_NAMESIZE];
bool do_unload;
__u32 prog_id;
bool reuse_maps;
char pin_dir[512];
char filename[512];
char progname[32];
char src_mac[18];
char dest_mac[18];
__u16 xsk_bind_flags;
int xsk_if_queue;
bool xsk_poll_mode;
bool unload_all;
bool show_stats; // 数据统计
bool ip_filter; //ip过滤
bool mac_filter; //mac过滤
bool router; //路由
bool state; //会话保持
bool clear; //清理

};

/* Defined in common_params.o */
extern int verbose;

/* Exit return codes */
#define EXIT_OK 0 /* == EXIT_SUCCESS (stdlib.h) man exit(3) */
#define EXIT_FAIL 1 /* == EXIT_FAILURE (stdlib.h) man exit(3) */
#define EXIT_FAIL_OPTION 2
#define EXIT_FAIL_XDP 30
#define EXIT_FAIL_BPF 40

#endif /* __COMMON_DEFINES_H */
162 changes: 162 additions & 0 deletions eBPF_Supermarket/Network_Subsystem/net_manager/common/common_libbpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/* Common function that with time should be moved to libbpf */

#include <errno.h>
#include <string.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>

#include "common_libbpf.h"

/* From: include/linux/err.h */
#define MAX_ERRNO 4095
#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO)
static inline bool IS_ERR_OR_NULL(const void *ptr)
{
return (!ptr) || IS_ERR_VALUE((unsigned long)ptr);
}

#define pr_warning printf

/* As close as possible to libbpf bpf_prog_load_xattr(), with the
* difference of handling pinned maps.
*/
int bpf_prog_load_xattr_maps(const struct bpf_prog_load_attr_maps *attr,
struct bpf_object **pobj, int *prog_fd)
{
struct bpf_object_open_attr open_attr = {
.file = attr->file,
.prog_type = attr->prog_type,
};
struct bpf_program *prog, *first_prog = NULL;
enum bpf_attach_type expected_attach_type;
enum bpf_prog_type prog_type;
struct bpf_object *obj;
struct bpf_map *map;
int err;
int i;

if (!attr)
return -EINVAL;
if (!attr->file)
return -EINVAL;


obj = bpf_object__open_xattr(&open_attr);
if (IS_ERR_OR_NULL(obj))
return -ENOENT;

bpf_object__for_each_program(prog, obj) {
/*
* If type is not specified, try to guess it based on
* section name.
*/
prog_type = attr->prog_type;
// Was: prog->prog_ifindex = attr->ifindex;
bpf_program__set_ifindex(prog, attr->ifindex);

expected_attach_type = attr->expected_attach_type;
#if 0 /* Use internal libbpf variables */
if (prog_type == BPF_PROG_TYPE_UNSPEC) {
err = bpf_program__identify_section(prog, &prog_type,
&expected_attach_type);
if (err < 0) {
bpf_object__close(obj);
return -EINVAL;
}
}
#endif

bpf_program__set_type(prog, prog_type);
bpf_program__set_expected_attach_type(prog,
expected_attach_type);

if (!first_prog)
first_prog = prog;
}

/* Reset attr->pinned_maps.map_fd to identify successful file load */
for (i = 0; i < attr->nr_pinned_maps; i++)
attr->pinned_maps[i].map_fd = -1;

bpf_map__for_each(map, obj) {
const char* mapname = bpf_map__name(map);

if (!bpf_map__is_offload_neutral(map))
bpf_map__set_ifindex(map, attr->ifindex);
/* Was: map->map_ifindex = attr->ifindex; */

for (i = 0; i < attr->nr_pinned_maps; i++) {
struct bpf_pinned_map *pin_map = &attr->pinned_maps[i];
int fd;

if (strcmp(mapname, pin_map->name) != 0)
continue;

/* Matched, try opening pinned file */
fd = bpf_obj_get(pin_map->filename);
if (fd > 0) {
/* Use FD from pinned map as replacement */
bpf_map__reuse_fd(map, fd);
/* TODO: Might want to set internal map "name"
* if opened pinned map didn't, to allow
* bpf_object__find_map_fd_by_name() to work.
*/
pin_map->map_fd = fd;
continue;
}
/* Could not open pinned filename map, then this prog
* should then pin the map, BUT this can only happen
* after bpf_object__load().
*/
}
}

if (!first_prog) {
pr_warning("object file doesn't contain bpf program\n");
bpf_object__close(obj);
return -ENOENT;
}

err = bpf_object__load(obj);
if (err) {
bpf_object__close(obj);
return -EINVAL;
}

/* Pin the maps that were not loaded via pinned filename */
bpf_map__for_each(map, obj) {
const char* mapname = bpf_map__name(map);

for (i = 0; i < attr->nr_pinned_maps; i++) {
struct bpf_pinned_map *pin_map = &attr->pinned_maps[i];
int err;

if (strcmp(mapname, pin_map->name) != 0)
continue;

/* Matched, check if map is already loaded */
if (pin_map->map_fd != -1)
continue;

/* Needs to be pinned */
err = bpf_map__pin(map, pin_map->filename);
if (err)
continue;
pin_map->map_fd = bpf_map__fd(map);
}
}

/* Help user if requested map name that doesn't exist */
for (i = 0; i < attr->nr_pinned_maps; i++) {
struct bpf_pinned_map *pin_map = &attr->pinned_maps[i];

if (pin_map->map_fd < 0)
pr_warning("%s() requested mapname:%s not seen\n",
__func__, pin_map->name);
}

*pobj = obj;
*prog_fd = bpf_program__fd(first_prog);
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Common function that with time should be moved to libbpf */
#ifndef __COMMON_LIBBPF_H
#define __COMMON_LIBBPF_H

struct bpf_pinned_map {
const char *name;
const char *filename;
int map_fd;
};

/* bpf_prog_load_attr extended */
struct bpf_prog_load_attr_maps {
const char *file;
enum bpf_prog_type prog_type;
enum bpf_attach_type expected_attach_type;
int ifindex;
int nr_pinned_maps;
struct bpf_pinned_map *pinned_maps;
};

int bpf_prog_load_xattr_maps(const struct bpf_prog_load_attr_maps *attr,
struct bpf_object **pobj, int *prog_fd);

#endif /* __COMMON_LIBBPF_H */
Loading

0 comments on commit eb8a0da

Please sign in to comment.