Skip to content

Commit

Permalink
Small fixes.
Browse files Browse the repository at this point in the history
Signed-off-by: fruffy <fruffy@nyu.edu>
  • Loading branch information
fruffy committed Aug 14, 2024
1 parent 4076b42 commit 98aac57
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 103 deletions.
3 changes: 1 addition & 2 deletions backends/ebpf/psa/examples/simple.p4
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,12 @@ struct local_metadata_t {

parser packet_parser(packet_in packet, out headers_t headers, inout local_metadata_t local_metadata, in psa_ingress_parser_input_metadata_t standard_metadata, in empty_metadata_t resub_meta, in empty_metadata_t recirc_meta) {
state start {
packet.extract(headers.ethernet);
transition accept;
}
}

control packet_deparser(packet_out packet, out empty_metadata_t clone_i2e_meta, out empty_metadata_t resubmit_meta, out empty_metadata_t normal_meta, inout headers_t headers, in local_metadata_t local_metadata, in psa_ingress_output_metadata_t istd) {
apply {
packet.emit(headers.ethernet);
}
}

Expand All @@ -78,6 +76,7 @@ control ingress(inout headers_t headers, inout local_metadata_t local_metadata,

apply {
// tbl_switching.apply();
send_to_port(ostd, (PortId_t) PORT0);
}

}
Expand Down
9 changes: 9 additions & 0 deletions backends/ebpf/psa/examples/simple.p4info.txtpb
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,12 @@
pkg_info {
arch: "psa"
}

actions {
preamble {
id: 27646489
name: "send_to_port"
alias: "send_to_port"
annotations: "@noWarn(\"unused\")"
}
}
195 changes: 96 additions & 99 deletions backends/ebpf/runtime/ebpf_kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License.
*/


/// This file contains all functions and definitions necessary for the kernel target C
/// code to compile. It must be included with any file generated by the p4c-ebpf kernel
/// compiler.
#ifndef BACKENDS_EBPF_RUNTIME_EBPF_KERNEL_H_
#define BACKENDS_EBPF_RUNTIME_EBPF_KERNEL_H_

#include "ebpf_common.h"
#include <bpf/bpf_endian.h> // definitions for bpf_ntohs etc...

#include <bpf/bpf_endian.h> // definitions for bpf_ntohs etc...
#include <string> // memcmp

#include "ebpf_common.h"

#undef htonl
#undef htons
Expand All @@ -35,28 +36,29 @@ limitations under the License.
#define bpf_htonll(x) htonll(x)
#endif

#define load_byte(data, b) (*(((u8*)(data)) + (b)))
#define load_half(data, b) bpf_ntohs(*(u16 *)((u8*)(data) + (b)))
#define load_word(data, b) bpf_ntohl(*(u32 *)((u8*)(data) + (b)))
#define load_dword(data, b) bpf_be64_to_cpu(*(u64 *)((u8*)(data) + (b)))
#define load_byte(data, b) (*(((u8 *)(data)) + (b)))
#define load_half(data, b) bpf_ntohs(*(u16 *)((u8 *)(data) + (b)))
#define load_word(data, b) bpf_ntohl(*(u32 *)((u8 *)(data) + (b)))
#define load_dword(data, b) bpf_be64_to_cpu(*(u64 *)((u8 *)(data) + (b)))

/// If we operate in user space we only need to include bpf.h and
/// define the userspace API macros.
/// For kernel programs we need to specify a list of kernel helpers. These are
/// taken from here: https://github.com/torvalds/linux/blob/master/tools/lib/bpf/bpf_helpers.h

#ifdef CONTROL_PLANE // BEGIN EBPF USER SPACE DEFINITIONS
#ifdef CONTROL_PLANE // BEGIN EBPF USER SPACE DEFINITIONS

#include <bpf/bpf.h> // bpf_obj_get/pin, bpf_map_update_elem
#include <bpf/bpf.h> // bpf_obj_get/pin, bpf_map_update_elem

#define BPF_USER_MAP_UPDATE_ELEM(index, key, value, flags)\
#define BPF_USER_MAP_UPDATE_ELEM(index, key, value, flags) \
bpf_map_update_elem(index, key, value, flags)
#define BPF_OBJ_PIN(table, name) bpf_obj_pin(table, name)
#define BPF_OBJ_GET(name) bpf_obj_get(name)

#else // BEGIN EBPF KERNEL DEFINITIONS
#else // BEGIN EBPF KERNEL DEFINITIONS

#include <linux/pkt_cls.h> // TC_ACT_OK, TC_ACT_SHOT

#include "linux/bpf.h" // types, and general bpf definitions
// This file contains the definitions of all the kernel bpf essentials
#include <bpf/bpf_helpers.h>
Expand All @@ -80,113 +82,108 @@ struct bpf_elf_map {
#define SK_BUFF struct __sk_buff

/// From iproute2, annotate table with BTF which allows to read types at runtime.
#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
struct ____btf_map_##name { \
type_key key; \
type_val value; \
}; \
struct ____btf_map_##name \
__attribute__ ((section(".maps." #name), used)) \
____btf_map_##name = {};
#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
struct ____btf_map_##name { \
type_key key; \
type_val value; \
}; \
struct ____btf_map_##name \
__attribute__((section(".maps." #name), used)) ____btf_map_##name = {};

#define REGISTER_START()
#ifndef BTF
/// Note: pinning exports the table name globally, do not remove.
#define REGISTER_TABLE(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
};
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
};
#define REGISTER_TABLE_INNER(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, ID, INNER_IDX) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
.id = ID, \
.inner_idx = INNER_IDX, \
};
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
.id = ID, \
.inner_idx = INNER_IDX, \
};
#define REGISTER_TABLE_OUTER(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, INNER_ID, INNER_NAME) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
.inner_id = INNER_ID, \
};
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
.inner_id = INNER_ID, \
};
#define REGISTER_TABLE_FLAGS(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, FLAGS) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = FLAGS, \
};
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = FLAGS, \
};
#else
#define REGISTER_TABLE(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES) \
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
} NAME SEC(".maps");
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
} NAME SEC(".maps");
#define REGISTER_TABLE_FLAGS(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, FLAGS) \
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__uint(map_flags, FLAGS); \
} NAME SEC(".maps");
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__uint(map_flags, FLAGS); \
} NAME SEC(".maps");
#define REGISTER_TABLE_INNER(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, ID, INNER_IDX) \
struct NAME { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
} NAME SEC(".maps");
struct NAME { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
} NAME SEC(".maps");
#define REGISTER_TABLE_OUTER(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, INNER_ID, INNER_NAME) \
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__array(values, struct INNER_NAME); \
} NAME SEC(".maps");
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__array(values, struct INNER_NAME); \
} NAME SEC(".maps");
#define REGISTER_TABLE_NO_KEY_TYPE(NAME, TYPE, KEY_SIZE, VALUE_TYPE, MAX_ENTRIES) \
struct { \
__uint(type, TYPE); \
__uint(key_size, KEY_SIZE); \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
} NAME SEC(".maps");
struct { \
__uint(type, TYPE); \
__uint(key_size, KEY_SIZE); \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
} NAME SEC(".maps");
#endif
#define REGISTER_END()

#define BPF_MAP_LOOKUP_ELEM(table, key) \
bpf_map_lookup_elem(&table, key)
#define BPF_MAP_UPDATE_ELEM(table, key, value, flags) \
bpf_map_update_elem(&table, key, value, flags)
#define BPF_MAP_DELETE_ELEM(table, key) \
bpf_map_delete_elem(&table, key)
#define BPF_USER_MAP_UPDATE_ELEM(index, key, value, flags)\
bpf_update_elem(index, key, value, flags)
#define BPF_MAP_LOOKUP_ELEM(table, key) bpf_map_lookup_elem(&table, key)
#define BPF_MAP_UPDATE_ELEM(table, key, value, flags) bpf_map_update_elem(&table, key, value, flags)
#define BPF_MAP_DELETE_ELEM(table, key) bpf_map_delete_elem(&table, key)
#define BPF_USER_MAP_UPDATE_ELEM(index, key, value, flags) bpf_update_elem(index, key, value, flags)
#define BPF_OBJ_PIN(table, name) bpf_obj_pin(table, name)
#define BPF_OBJ_GET(name) bpf_obj_get(name)

#endif // END EBPF KERNEL DEFINITIONS
#endif // END EBPF KERNEL DEFINITIONS

#endif // BACKENDS_EBPF_RUNTIME_EBPF_KERNEL_H_
4 changes: 2 additions & 2 deletions backends/ebpf/tests/ptf/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ def runTest(self) -> None:
# check no connectivity if switching rules are not installed
pkt = testutils.simple_udp_packet(eth_dst="00:00:00:00:00:03")
testutils.send_packet(self, PORT0, pkt)
# testutils.verify_packet(self, pkt, PORT0)
testutils.verify_any_packet_any_port(self, [pkt], ALL_PORTS)
testutils.verify_packet(self, pkt, PORT0)
# testutils.verify_any_packet_any_port(self, [], ALL_PORTS)

0 comments on commit 98aac57

Please sign in to comment.