From 9635f71ee3a77d0fedde336630f4864127c4139f Mon Sep 17 00:00:00 2001 From: "Komal, Jain" Date: Thu, 21 Nov 2024 10:42:06 +0530 Subject: [PATCH] Align key components to the nearest 8-bit size Signed-off-by: Komal, Jain --- backends/ebpf/codeGen.cpp | 120 +++++++--- backends/ebpf/codeGen.h | 6 +- backends/ebpf/ebpfBackend.cpp | 2 +- backends/ebpf/ebpfParser.cpp | 10 +- backends/ebpf/ebpfParser.h | 1 + backends/ebpf/ebpfType.cpp | 62 ++++- backends/ebpf/ebpfType.h | 18 +- backends/ebpf/psa/backend.cpp | 2 +- backends/ebpf/target.h | 5 + backends/tc/CMakeLists.txt | 1 + backends/tc/backend.cpp | 2 +- backends/tc/ebpfCodeGen.cpp | 212 +++++++++++++++--- backends/tc/ebpfCodeGen.h | 2 + .../add_entry_1_example_control_blocks.c | 14 +- .../add_entry_1_example_parser.c | 2 +- .../add_entry_1_example_parser.h | 53 ++++- .../add_entry_3_example_control_blocks.c | 14 +- .../add_entry_3_example_parser.c | 2 +- .../add_entry_3_example_parser.h | 53 ++++- .../add_entry_example_parser.h | 49 +++- .../calculator_control_blocks.c | 36 +-- .../p4tc_samples_outputs/calculator_parser.c | 10 +- .../p4tc_samples_outputs/calculator_parser.h | 49 +++- .../checksum_control_blocks.c | 8 +- .../p4tc_samples_outputs/checksum_parser.h | 49 +++- .../const_entries_range_mask_parser.h | 45 ++++ ...default_action_example_01_control_blocks.c | 4 +- .../default_action_example_01_parser.c | 4 +- .../default_action_example_01_parser.h | 49 +++- .../default_action_example_control_blocks.c | 4 +- .../default_action_example_parser.c | 4 +- .../default_action_example_parser.h | 49 +++- ...ault_action_with_param_01_control_blocks.c | 4 +- .../default_action_with_param_01_parser.c | 4 +- .../default_action_with_param_01_parser.h | 49 +++- ...default_action_with_param_control_blocks.c | 4 +- .../default_action_with_param_parser.c | 4 +- .../default_action_with_param_parser.h | 49 +++- ...default_hit_const_example_control_blocks.c | 4 +- .../default_hit_const_example_parser.c | 4 +- .../default_hit_const_example_parser.h | 49 +++- .../digest_01_control_blocks.c | 8 +- .../p4tc_samples_outputs/digest_01_parser.h | 51 ++++- .../digest_control_blocks.c | 10 +- testdata/p4tc_samples_outputs/digest_parser.h | 51 ++++- .../digest_parser_meta_control_blocks.c | 8 +- .../digest_parser_meta_parser.h | 49 +++- .../direct_counter_example_control_blocks.c | 8 +- .../direct_counter_example_parser.h | 49 +++- .../direct_meter_color_parser.h | 49 +++- .../direct_meter_parser.h | 49 +++- .../drop_packet_example_control_blocks.c | 4 +- .../drop_packet_example_parser.c | 4 +- .../drop_packet_example_parser.h | 49 +++- .../global_action_example_01_control_blocks.c | 12 +- .../global_action_example_01_parser.h | 49 +++- .../global_action_example_02_control_blocks.c | 16 +- .../global_action_example_02_parser.h | 49 +++- testdata/p4tc_samples_outputs/hash1_parser.h | 49 +++- testdata/p4tc_samples_outputs/hash_parser.h | 49 +++- ...direct_counter_01_example_control_blocks.c | 8 +- .../indirect_counter_01_example_parser.h | 49 +++- .../internetchecksum_01_control_blocks.c | 4 +- .../internetchecksum_01_parser.h | 49 +++- .../ipip_control_blocks.c | 4 +- testdata/p4tc_samples_outputs/ipip_parser.h | 49 +++- .../is_host_port_control_blocks.c | 8 +- .../is_host_port_parser.h | 49 +++- .../is_net_port_control_blocks.c | 8 +- .../p4tc_samples_outputs/is_net_port_parser.h | 49 +++- .../matchtype_control_blocks.c | 4 +- .../p4tc_samples_outputs/matchtype_parser.c | 4 +- .../p4tc_samples_outputs/matchtype_parser.h | 49 +++- .../p4tc_samples_outputs/meter_color_parser.h | 49 +++- testdata/p4tc_samples_outputs/meter_parser.h | 49 +++- .../mix_matchtype_example_control_blocks.c | 4 +- .../mix_matchtype_example_parser.c | 4 +- .../mix_matchtype_example_parser.h | 49 +++- ...ultiple_tables_example_01_control_blocks.c | 4 +- .../multiple_tables_example_01_parser.c | 4 +- .../multiple_tables_example_01_parser.h | 49 +++- ...ultiple_tables_example_02_control_blocks.c | 4 +- .../multiple_tables_example_02_parser.c | 4 +- .../multiple_tables_example_02_parser.h | 49 +++- .../name_annotation_example_control_blocks.c | 4 +- .../name_annotation_example_parser.c | 4 +- .../name_annotation_example_parser.h | 49 +++- .../no_table_example_control_blocks.c | 4 +- .../no_table_example_parser.c | 4 +- .../no_table_example_parser.h | 49 +++- .../noaction_example_01_control_blocks.c | 4 +- .../noaction_example_01_parser.c | 4 +- .../noaction_example_01_parser.h | 49 +++- .../noaction_example_02_control_blocks.c | 4 +- .../noaction_example_02_parser.c | 4 +- .../noaction_example_02_parser.h | 49 +++- ...ummask_annotation_example_control_blocks.c | 4 +- .../nummask_annotation_example_parser.c | 4 +- .../nummask_annotation_example_parser.h | 49 +++- .../send_to_port_example_control_blocks.c | 4 +- .../send_to_port_example_parser.c | 4 +- .../send_to_port_example_parser.h | 49 +++- .../set_entry_timer_example_control_blocks.c | 4 +- .../set_entry_timer_example_parser.c | 4 +- .../set_entry_timer_example_parser.h | 49 +++- .../simple_exact_example_control_blocks.c | 8 +- .../simple_exact_example_parser.h | 49 +++- .../simple_extern_example_control_blocks.c | 8 +- .../simple_extern_example_parser.h | 49 +++- .../simple_lpm_example_control_blocks.c | 8 +- .../simple_lpm_example_parser.h | 49 +++- .../simple_ternary_example_control_blocks.c | 8 +- .../simple_ternary_example_parser.h | 49 +++- .../size_param_example_control_blocks.c | 4 +- .../size_param_example_parser.c | 4 +- .../size_param_example_parser.h | 49 +++- ...c_may_override_example_01_control_blocks.c | 4 +- .../tc_may_override_example_01_parser.c | 4 +- .../tc_may_override_example_01_parser.h | 49 +++- ...c_may_override_example_02_control_blocks.c | 4 +- .../tc_may_override_example_02_parser.c | 4 +- .../tc_may_override_example_02_parser.h | 49 +++- ...c_may_override_example_03_control_blocks.c | 4 +- .../tc_may_override_example_03_parser.c | 4 +- .../tc_may_override_example_03_parser.h | 49 +++- ...c_may_override_example_04_control_blocks.c | 4 +- .../tc_may_override_example_04_parser.c | 4 +- .../tc_may_override_example_04_parser.h | 49 +++- ...c_may_override_example_05_control_blocks.c | 4 +- .../tc_may_override_example_05_parser.c | 4 +- .../tc_may_override_example_05_parser.h | 49 +++- ...c_may_override_example_06_control_blocks.c | 4 +- .../tc_may_override_example_06_parser.c | 4 +- .../tc_may_override_example_06_parser.h | 49 +++- ...c_may_override_example_07_control_blocks.c | 4 +- .../tc_may_override_example_07_parser.c | 4 +- .../tc_may_override_example_07_parser.h | 49 +++- ...c_may_override_example_08_control_blocks.c | 4 +- .../tc_may_override_example_08_parser.c | 4 +- .../tc_may_override_example_08_parser.h | 49 +++- ...c_may_override_example_09_control_blocks.c | 4 +- .../tc_may_override_example_09_parser.c | 4 +- .../tc_may_override_example_09_parser.h | 49 +++- .../tc_type_annotation_example_parser.h | 49 +++- .../test_ipv6_example_control_blocks.c | 2 +- .../test_ipv6_example_parser.c | 2 +- .../test_ipv6_example_parser.h | 51 ++++- 147 files changed, 3232 insertions(+), 397 deletions(-) diff --git a/backends/ebpf/codeGen.cpp b/backends/ebpf/codeGen.cpp index db05340e817..0e0cd44e68f 100644 --- a/backends/ebpf/codeGen.cpp +++ b/backends/ebpf/codeGen.cpp @@ -351,7 +351,6 @@ void CodeGenInspector::emitAssignStatement(const IR::Type *ltype, const IR::Expr width = scalar->implementationWidthInBits(); memcpy = !EBPFScalarType::generatesScalar(width); } - builder->emitIndent(); if (memcpy) { builder->append("__builtin_memcpy(&"); @@ -367,15 +366,15 @@ void CodeGenInspector::emitAssignStatement(const IR::Type *ltype, const IR::Expr visit(rexpr); builder->appendFormat(", %d)", scalar->bytesRequired()); } else { - if (lexpr != nullptr) { - visit(lexpr); - } else { - builder->append(lpath); - } - builder->append(" = "); if (builder->target->name == "P4TC") { - emitTCAssignmentEndianessConversion(lexpr, rexpr); + emitTCAssignmentEndianessConversion(ltype, lexpr, rexpr, lpath); } else { + if (lexpr != nullptr) { + visit(lexpr); + } else { + builder->append(lpath); + } + builder->append(" = "); visit(rexpr); } } @@ -492,7 +491,7 @@ void CodeGenInspector::emitAndConvertByteOrder(const IR::Expression *expr, cstri } unsigned shift = loadSize - widthToEmit; builder->appendFormat("%v(", emit); - visit(expr); + getBitAlignment(expr); if (shift != 0 && byte_order == "HOST") builder->appendFormat(" << %d", shift); builder->append(")"); } @@ -512,7 +511,7 @@ void CodeGenInspector::emitTCBinaryOperation(const IR::Operation_Binary *b, bool rByteOrder = tcTarget->getByteOrder(typeMap, action, rexpr); } if (lByteOrder == rByteOrder) { - visit(lexpr); + getBitAlignment(lexpr); if (isScalar) { builder->spc(); builder->append(stringop); @@ -521,7 +520,7 @@ void CodeGenInspector::emitTCBinaryOperation(const IR::Operation_Binary *b, bool builder->append(", &"); } if (!b->is()) expressionPrecedence = b->getPrecedence() + 1; - visit(rexpr); + getBitAlignment(rexpr); return; } if (lByteOrder == "NETWORK") { @@ -542,14 +541,14 @@ void CodeGenInspector::emitTCBinaryOperation(const IR::Operation_Binary *b, bool builder->append(", &"); } if (!b->is()) expressionPrecedence = b->getPrecedence() + 1; - visit(rexpr); + getBitAlignment(rexpr); return; } else if (rByteOrder == "NETWORK") { // ConvertRight auto ftype = typeMap->getType(rexpr); auto et = EBPFTypeFactory::instance->create(ftype); unsigned width = dynamic_cast(et)->widthInBits(); - visit(lexpr); + getBitAlignment(rexpr); if (isScalar) { builder->spc(); builder->append(stringop); @@ -567,8 +566,19 @@ void CodeGenInspector::emitTCBinaryOperation(const IR::Operation_Binary *b, bool return; } -void CodeGenInspector::emitTCAssignmentEndianessConversion(const IR::Expression *lexpr, - const IR::Expression *rexpr) { +void CodeGenInspector::emitTCAssignmentEndianessConversion(const IR::Type *ltype, + const IR::Expression *lexpr, + const IR::Expression *rexpr, + cstring lpath) { + bool needsBitAlignment = storeBitAlignment(ltype, lexpr, lpath); + if (!needsBitAlignment) { + if (lexpr != nullptr) { + visit(lexpr); + } else { + builder->append(lpath); + } + builder->append(" = "); + } auto action = findContext(); auto b = dynamic_cast(builder->target); cstring lByteOrder = "HOST"_cs, rByteOrder = "HOST"_cs; @@ -578,18 +588,14 @@ void CodeGenInspector::emitTCAssignmentEndianessConversion(const IR::Expression if (rexpr) { rByteOrder = b->getByteOrder(typeMap, action, rexpr); } - if (lByteOrder == rByteOrder) { - visit(rexpr); - return; - } auto ftype = typeMap->getType(rexpr); auto et = EBPFTypeFactory::instance->create(ftype); unsigned width = dynamic_cast(et)->widthInBits(); if (width <= 8) { visit(rexpr); - return; - } - if (rByteOrder == "NETWORK") { + } else if (lByteOrder == rByteOrder) { + getBitAlignment(rexpr); + } else if (rByteOrder == "NETWORK") { // If left side of assignment is not annotated field i.e host endian and right expression // is annotated field i.e network endian, we need to convert rexp to host order. // Example - @@ -597,8 +603,7 @@ void CodeGenInspector::emitTCAssignmentEndianessConversion(const IR::Expression // select_0 = bntoh(hdr.ipv4.diffserv) // emitAndConvertByteOrder(rexpr, "HOST"_cs); - } - if (lByteOrder == "NETWORK") { + } else if (lByteOrder == "NETWORK") { // If left side of assignment is annotated field i.e network endian, we need to convert // right expression to network order. // Example - @@ -607,8 +612,73 @@ void CodeGenInspector::emitTCAssignmentEndianessConversion(const IR::Expression // emitAndConvertByteOrder(rexpr, "NETWORK"_cs); } + if (needsBitAlignment) { + builder->append("))"); + } +} - return; +bool CodeGenInspector::storeBitAlignment(const IR::Type *ltype, const IR::Expression *lexpr, + cstring lpath) { + auto tcTarget = dynamic_cast(builder->target); + if (lexpr != nullptr) { + if (!(lexpr->is() || lexpr->is())) { + return false; + } + } + auto ebpfType = EBPFTypeFactory::instance->create(ltype); + EBPFScalarType *scalar = nullptr; + if (ebpfType->is()) { + scalar = ebpfType->to(); + bool primitive = tcTarget->isPrimitiveByteAligned(scalar->implementationWidthInBits()); + if (primitive) { + return false; + } else { + cstring storePrimitive = scalar->implementationWidthInBits() < 32 + ? "storePrimitive32"_cs + : "storePrimitive64"_cs; + builder->appendFormat("%v((u8 *)&", storePrimitive); + if (lexpr != nullptr) { + visit(lexpr); + } else { + builder->append(lpath); + } + builder->appendFormat(", %d, (", scalar->implementationWidthInBits()); + return true; + } + } + return false; +} + +void CodeGenInspector::getBitAlignment(const IR::Expression *expression) { + if (expression->is() || expression->is()) { + auto ftype = typeMap->getType(expression); + if (!ftype) { + visit(expression); + return; + } + auto tcTarget = dynamic_cast(builder->target); + auto ebpfType = EBPFTypeFactory::instance->create(ftype); + EBPFScalarType *scalar = nullptr; + if (ebpfType->is()) { + scalar = ebpfType->to(); + bool isPrimitive = + tcTarget->isPrimitiveByteAligned(scalar->implementationWidthInBits()); + if (!isPrimitive) { + cstring getPrimitive = scalar->implementationWidthInBits() < 32 + ? "getPrimitive32"_cs + : "getPrimitive64"_cs; + builder->appendFormat("%v((u8 *)", getPrimitive); + visit(expression); + builder->appendFormat(", %d)", scalar->implementationWidthInBits()); + } else { + visit(expression); + } + } else { + visit(expression); + } + } else { + visit(expression); + } } unsigned EBPFInitializerUtils::ebpfTypeWidth(P4::TypeMap *typeMap, const IR::Expression *expr) { diff --git a/backends/ebpf/codeGen.h b/backends/ebpf/codeGen.h index ebc4b8eb40b..a359f38ca0e 100644 --- a/backends/ebpf/codeGen.h +++ b/backends/ebpf/codeGen.h @@ -128,8 +128,10 @@ class CodeGenInspector : public Inspector { void widthCheck(const IR::Node *node) const; void emitAndConvertByteOrder(const IR::Expression *expr, cstring byte_order); void emitTCBinaryOperation(const IR::Operation_Binary *b, bool isScalar); - void emitTCAssignmentEndianessConversion(const IR::Expression *lexpr, - const IR::Expression *rexpr); + void emitTCAssignmentEndianessConversion(const IR::Type *ltype, const IR::Expression *lexpr, + const IR::Expression *rexpr, cstring lpath); + void getBitAlignment(const IR::Expression *expression); + bool storeBitAlignment(const IR::Type *ltype, const IR::Expression *lexpr, cstring lpath); }; class EBPFInitializerUtils { diff --git a/backends/ebpf/ebpfBackend.cpp b/backends/ebpf/ebpfBackend.cpp index 86477f45138..f9b074f0ed6 100644 --- a/backends/ebpf/ebpfBackend.cpp +++ b/backends/ebpf/ebpfBackend.cpp @@ -32,7 +32,7 @@ void emitFilterModel(const EbpfOptions &options, Target *target, const IR::Tople CodeBuilder c(target); CodeBuilder h(target); - EBPFTypeFactory::createFactory(typeMap); + EBPFTypeFactory::createFactory(typeMap, false); auto ebpfprog = new EBPFProgram(options, toplevel->getProgram(), refMap, typeMap, toplevel); if (!ebpfprog->build()) return; diff --git a/backends/ebpf/ebpfParser.cpp b/backends/ebpf/ebpfParser.cpp index 85eaaa1fbc0..9183300f7eb 100644 --- a/backends/ebpf/ebpfParser.cpp +++ b/backends/ebpf/ebpfParser.cpp @@ -185,17 +185,17 @@ bool StateTranslationVisitor::preorder(const IR::SelectExpression *expression) { BUG_CHECK(expression->select->components.size() == 1, "%1%: tuple not eliminated in select", expression->select); selectValue = state->parser->program->refMap->newName("select"); - auto type = state->parser->program->typeMap->getType(expression->select, true); - if (auto list = type->to()) { + selectType = state->parser->program->typeMap->getType(expression->select, true); + if (auto list = selectType->to()) { BUG_CHECK(list->components.size() == 1, "%1% list type with more than 1 element", list); - type = list->components.at(0); + selectType = list->components.at(0); } - auto etype = EBPFTypeFactory::instance->create(type); + auto etype = EBPFTypeFactory::instance->create(selectType); builder->emitIndent(); etype->declare(builder, selectValue, false); builder->endOfStatement(true); - emitAssignStatement(type, nullptr, selectValue, expression->select->components.at(0)); + emitAssignStatement(selectType, nullptr, selectValue, expression->select->components.at(0)); builder->newline(); // Init value_sets diff --git a/backends/ebpf/ebpfParser.h b/backends/ebpf/ebpfParser.h index 42b645a2e8d..a88debcf7f3 100644 --- a/backends/ebpf/ebpfParser.h +++ b/backends/ebpf/ebpfParser.h @@ -32,6 +32,7 @@ class StateTranslationVisitor : public CodeGenInspector { protected: /// Stores the result of evaluating the select argument. cstring selectValue; + const IR::Type *selectType; P4::P4CoreLibrary &p4lib; const EBPFParserState *state; diff --git a/backends/ebpf/ebpfType.cpp b/backends/ebpf/ebpfType.cpp index 10f4f7a26aa..8cb91d02dc4 100644 --- a/backends/ebpf/ebpfType.cpp +++ b/backends/ebpf/ebpfType.cpp @@ -19,6 +19,7 @@ limitations under the License. namespace P4::EBPF { EBPFTypeFactory *EBPFTypeFactory::instance; +bool EBPFTypeFactory::isTC; EBPFType *EBPFTypeFactory::create(const IR::Type *type) { CHECK_NULL(type); @@ -27,7 +28,11 @@ EBPFType *EBPFTypeFactory::create(const IR::Type *type) { if (type->is()) { result = new EBPFBoolType(); } else if (auto bt = type->to()) { - result = new EBPFScalarType(bt); + if (EBPFTypeFactory::isTC) { + result = new EBPFScalarTypePNA(bt); + } else { + result = new EBPFScalarType(bt); + } } else if (auto st = type->to()) { result = new EBPFStructType(st); } else if (auto tt = type->to()) { @@ -384,4 +389,59 @@ void EBPFMethodDeclaration::emit(CodeBuilder *builder) { builder->newline(); } +unsigned EBPFScalarTypePNA::alignment() const { + if (width <= 8) + return 1; + else if (width <= 16) + return 2; + else if (width <= 24) + return 1; // compiled as u8* + else if (width <= 32) + return 4; + else if (width <= 56) + return 1; // compiled as u8* + else if (width <= 64) + return 8; + else + // compiled as u8* + return 1; +} + +void EBPFScalarTypePNA::declare(CodeBuilder *builder, cstring id, bool asPointer) { + if (generatesScalar(width) && isPrimitiveByteAligned == true) { + emit(builder); + if (asPointer) builder->append("*"); + builder->spc(); + builder->append(id); + } else { + if (asPointer) + builder->appendFormat("u8* %s", id.c_str()); + else + builder->appendFormat("u8 %s[%d]", id.c_str(), bytesRequired()); + } +} + +void EBPFScalarTypePNA::declareInit(CodeBuilder *builder, cstring id, bool asPointer) { + if (generatesScalar(width) && isPrimitiveByteAligned == true) { + emit(builder); + if (asPointer) builder->append("*"); + builder->spc(); + id = id + cstring(" = 0"); + builder->append(id); + } else { + if (asPointer) + builder->appendFormat("u8* %s = NULL", id.c_str()); + else + builder->appendFormat("u8 %s[%d] = {0}", id.c_str(), bytesRequired()); + } +} + +void EBPFScalarTypePNA::emitInitializer(CodeBuilder *builder) { + if (generatesScalar(width) && isPrimitiveByteAligned == true) { + builder->append("0"); + } else { + builder->append("{ 0 }"); + } +} + } // namespace P4::EBPF diff --git a/backends/ebpf/ebpfType.h b/backends/ebpf/ebpfType.h index c3493b6affc..e160cb58906 100644 --- a/backends/ebpf/ebpfType.h +++ b/backends/ebpf/ebpfType.h @@ -62,8 +62,10 @@ class EBPFTypeFactory { public: static EBPFTypeFactory *instance; - static void createFactory(const P4::TypeMap *typeMap) { + static bool isTC; + static void createFactory(const P4::TypeMap *typeMap, bool TC) { EBPFTypeFactory::instance = new EBPFTypeFactory(typeMap); + EBPFTypeFactory::isTC = TC; } virtual EBPFType *create(const IR::Type *type); }; @@ -223,6 +225,20 @@ class EBPFMethodDeclaration : public EBPFObject { DECLARE_TYPEINFO(EBPFMethodDeclaration, EBPFObject); }; +class EBPFScalarTypePNA : public EBPFScalarType { + bool isPrimitiveByteAligned = false; + + public: + explicit EBPFScalarTypePNA(const IR::Type_Bits *bits) : EBPFScalarType(bits) { + isPrimitiveByteAligned = (width <= 8 || width <= 16 || (width > 24 && width <= 32) || + (width > 56 && width <= 64)); + } + unsigned alignment() const; + void declare(CodeBuilder *builder, cstring id, bool asPointer); + void declareInit(CodeBuilder *builder, cstring id, bool asPointer); + void emitInitializer(CodeBuilder *builder); +}; + } // namespace P4::EBPF #endif /* BACKENDS_EBPF_EBPFTYPE_H_ */ diff --git a/backends/ebpf/psa/backend.cpp b/backends/ebpf/psa/backend.cpp index 03293b15908..4fb9c01fc87 100644 --- a/backends/ebpf/psa/backend.cpp +++ b/backends/ebpf/psa/backend.cpp @@ -61,7 +61,7 @@ void PSASwitchBackend::convert(const IR::ToplevelBlock *tlb) { main->apply(*parsePsaArch); program = toplevel->getProgram(); - EBPFTypeFactory::createFactory(typeMap); + EBPFTypeFactory::createFactory(typeMap, false); auto *convertToEbpfPSA = new ConvertToEbpfPSA(options, refMap, typeMap); PassManager toEBPF = { new P4::DiscoverStructure(&structure), diff --git a/backends/ebpf/target.h b/backends/ebpf/target.h index b624c2718d6..3fdeab7c789 100644 --- a/backends/ebpf/target.h +++ b/backends/ebpf/target.h @@ -237,6 +237,11 @@ class P4TCTarget : public KernelSamplesTarget { } return "HOST"_cs; } + + bool isPrimitiveByteAligned(int width) const { + return (width <= 8 || width <= 16 || (width > 24 && width <= 32) || + (width > 56 && width <= 64)); + } }; /// Target XDP. diff --git a/backends/tc/CMakeLists.txt b/backends/tc/CMakeLists.txt index 92f308fea97..2e3ab1594f5 100644 --- a/backends/tc/CMakeLists.txt +++ b/backends/tc/CMakeLists.txt @@ -63,6 +63,7 @@ set(P4TC_BACKEND_HEADERS pnaProgramStructure.h tcAnnotations.h tcExterns.h + handleBitAlignment.h version.h ../ebpf/codeGen.h ../ebpf/ebpfBackend.h diff --git a/backends/tc/backend.cpp b/backends/tc/backend.cpp index 5f894a5de0b..d8bb1711714 100644 --- a/backends/tc/backend.cpp +++ b/backends/tc/backend.cpp @@ -101,7 +101,7 @@ bool Backend::ebpfCodeGen(P4::ReferenceMap *refMapEBPF, P4::TypeMap *typeMapEBPF main->apply(*parsePnaArch); program = top->getProgram(); - EBPF::EBPFTypeFactory::createFactory(typeMapEBPF); + EBPF::EBPFTypeFactory::createFactory(typeMapEBPF, true); auto convertToEbpf = new ConvertToEbpfPNA(ebpfOption, refMapEBPF, typeMapEBPF, tcIR); PassManager toEBPF = { new P4::DiscoverStructure(&structure), diff --git a/backends/tc/ebpfCodeGen.cpp b/backends/tc/ebpfCodeGen.cpp index 00d6d66733a..a03e1725265 100644 --- a/backends/tc/ebpfCodeGen.cpp +++ b/backends/tc/ebpfCodeGen.cpp @@ -212,6 +212,60 @@ void PNAArchTC::emitInstances(EBPF::CodeBuilder *builder) const { builder->newline(); } +void PNAArchTC::emitGlobalFunctions(EBPF::CodeBuilder *builder) const { + const char *code = + "u32 getPrimitive32(u8 *a, int size) {\n" + " if(size <=32 || size >=56) {\n" + " error(\"Invalid size.\");\n" + " };\n" + " return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]);\n" + "}\n" + "u64 getPrimitive64(u8 *a, int size) {\n" + " if(size <=32 || size >=56) {\n" + " error(\"Invalid size.\");\n" + " };\n" + " if(size <= 40) {\n" + " return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | " + "(((u64)a[1]) << 8) | a[0]);\n" + " } else {\n" + " if(size <= 48) {\n" + " return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | " + "(((u64)a[2]) << 16) | (((u64)a[1]) << " + "8) | a[0]);\n" + " } else {\n" + " return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | " + "(((u64)a[3]) << 24) | (((u64)a[2]) << " + "16) | (((u64)a[1]) << 8) | a[0]);\n" + " }\n" + " }\n" + "}\n" + "void storePrimitive32(u8 *a, u32 value, int size) {\n" + " if(size <=16 || size >=24) {\n" + " error(\"Invalid size.\");\n" + " };\n" + " a[0] = (u8)(value);\n" + " a[1] = (u8)(value >> 8);\n" + " a[2] = (u8)(value >> 16);\n" + "}\n" + "void storePrimitive64(u8 *a, int size, u64 value) {\n" + " if(size <=32 || size >=56) {\n" + " error(\"Invalid size.\");\n" + " };\n" + " a[0] = (u8)(value);\n" + " a[1] = (u8)(value >> 8);\n" + " a[2] = (u8)(value >> 16);\n" + " a[3] = (u8)(value >> 24);\n" + " a[4] = (u8)(value >> 32);\n" + " if (size <= 48) {\n" + " a[5] = (u8)(value >> 40);\n" + " }\n" + " if (size > 48 && size <= 56){\n" + " a[6] = (u8)(value >> 48);\n" + " }\n" + "}\n"; + builder->appendLine(code); +} + void PNAArchTC::emitParser(EBPF::CodeBuilder *builder) const { /** * Structure of a C Parser program for PNA @@ -248,6 +302,7 @@ void PNAArchTC::emitHeader(EBPF::CodeBuilder *builder) const { emitP4TCFilterFields(builder); // BPF map definitions. emitInstances(builder); + emitGlobalFunctions(builder); } // =====================TCIngressPipelinePNA============================= @@ -633,6 +688,8 @@ void PnaStateTranslationVisitor::compileExtractField(const IR::Expression *expr, } } } + auto tcTarget = dynamic_cast(builder->target); + bool isPrimitive = tcTarget->isPrimitiveByteAligned(widthToExtract); msgStr = absl::StrFormat("Parser: extracting field %v", fieldName); builder->target->emitTraceMessage(builder, msgStr.c_str()); @@ -667,19 +724,38 @@ void PnaStateTranslationVisitor::compileExtractField(const IR::Expression *expr, builder->appendFormat(".%v, %v + BYTES(%v), %d)", fieldName, program->packetStartVar, program->offsetVar, widthToExtract / 8); } else { - visit(expr); - builder->appendFormat(".%v = (", fieldName); - type->emit(builder); - builder->appendFormat(")((%s(%v, BYTES(%v))", helper, program->packetStartVar, - program->offsetVar); - if (shift != 0) builder->appendFormat(" >> %d", shift); - builder->append(")"); - if (widthToExtract != loadSize) { - builder->append(" & EBPF_MASK("); + if (!isPrimitive) { + cstring storePrimitive = + widthToExtract < 32 ? "storePrimitive32"_cs : "storePrimitive64"_cs; + builder->appendFormat("%v((u8 *)&", storePrimitive); + visit(expr); + builder->appendFormat(".%v, %d, (", fieldName, widthToExtract); type->emit(builder); - builder->appendFormat(", %d)", widthToExtract); + builder->appendFormat(")((%s(%v, BYTES(%v))", helper, program->packetStartVar, + program->offsetVar); + if (shift != 0) builder->appendFormat(" >> %d", shift); + builder->append(")"); + if (widthToExtract != loadSize) { + builder->append(" & EBPF_MASK("); + type->emit(builder); + builder->appendFormat(", %d)", widthToExtract); + } + builder->append("))"); + } else { + visit(expr); + builder->appendFormat(".%v = (", fieldName); + type->emit(builder); + builder->appendFormat(")((%s(%v, BYTES(%v))", helper, program->packetStartVar, + program->offsetVar); + if (shift != 0) builder->appendFormat(" >> %d", shift); + builder->append(")"); + if (widthToExtract != loadSize) { + builder->append(" & EBPF_MASK("); + type->emit(builder); + builder->appendFormat(", %d)", widthToExtract); + } + builder->append(")"); } - builder->append(")"); } builder->endOfStatement(true); } else { @@ -808,6 +884,71 @@ void PnaStateTranslationVisitor::compileLookahead(const IR::Expression *destinat builder->blockEnd(true); } +bool PnaStateTranslationVisitor::preorder(const IR::SelectCase *selectCase) { + unsigned width = EBPF::EBPFInitializerUtils::ebpfTypeWidth(typeMap, selectCase->keyset); + bool scalar = EBPF::EBPFScalarType::generatesScalar(width); + auto ebpfType = EBPF::EBPFTypeFactory::instance->create(selectType); + unsigned selectWidth = 0; + if (ebpfType->is()) { + selectWidth = ebpfType->to()->implementationWidthInBits(); + } + auto tcTarget = dynamic_cast(builder->target); + bool isPrimitive = tcTarget->isPrimitiveByteAligned(selectWidth); + + builder->emitIndent(); + if (auto pe = selectCase->keyset->to()) { + builder->append("if ("); + cstring pvsName = pe->path->name.name; + auto pvs = state->parser->getValueSet(pvsName); + if (pvs) pvs->emitLookup(builder); + builder->append(" != NULL)"); + } else if (auto mask = selectCase->keyset->to()) { + if (scalar) { + if (!isPrimitive) { + cstring getPrimitive = selectWidth < 32 ? "getPrimitive32"_cs : "getPrimitive64"_cs; + builder->appendFormat("if ((%v((u8 *)%v, %d)", getPrimitive, selectValue, + selectWidth); + } else { + builder->appendFormat("if ((%v", selectValue); + } + builder->append(" & "); + visit(mask->right); + builder->append(") == ("); + visit(mask->left); + builder->append(" & "); + visit(mask->right); + builder->append("))"); + } else { + unsigned bytes = ROUNDUP(width, 8); + bool first = true; + cstring hex = EBPF::EBPFInitializerUtils::genHexStr( + mask->right->to()->value, width, mask->right); + cstring value = EBPF::EBPFInitializerUtils::genHexStr( + mask->left->to()->value, width, mask->left); + builder->append("if ("); + for (unsigned i = 0; i < bytes; ++i) { + if (!first) { + builder->append(" && "); + } + builder->appendFormat("((%v[%u] & 0x%v)", selectValue, i, hex.substr(2 * i, 2)); + builder->append(" == "); + builder->appendFormat("(%v & %v))", value.substr(2 * i, 2), hex.substr(2 * i, 2)); + first = false; + } + builder->append(") "); + } + } else { + builder->appendFormat("if (%v", selectValue); + builder->append(" == "); + visit(selectCase->keyset); + builder->append(")"); + } + builder->append("goto "); + visit(selectCase->state); + builder->endOfStatement(true); + return false; +} + // =====================EBPFTablePNA============================= void EBPFTablePNA::emitKeyType(EBPF::CodeBuilder *builder) { builder->emitIndent(); @@ -1743,10 +1884,11 @@ void ControlBodyTranslatorPNA::processFunction(const P4::ExternFunction *functio actionName); } builder->emitIndent(); - builder->appendFormat("update_act_bpf_val->u.%v.%v = ", actionExtName, - param); - visit(components.at(index)->expression); - builder->endOfStatement(); + cstring value = "update_act_bpf_val->u."_cs + actionExtName + "."_cs + + param->toString(); + auto valuetype = typeMap->getType(param, true); + emitAssignStatement(valuetype, nullptr, value, + components.at(index)->expression); builder->newline(); } builder->emitIndent(); @@ -1895,14 +2037,13 @@ void ControlBodyTranslatorPNA::processApply(const P4::ApplyMethod *method) { builder->emitIndent(); if (memcpy) { - builder->appendFormat("__builtin_memcpy(&(%s.%s[0]), &(", keyname.c_str(), - fieldName.c_str()); + builder->appendFormat("__builtin_memcpy(&(%v.%v[0]), &(", keyname, fieldName); table->codeGen->visit(c->expression); builder->appendFormat("[0]), %d)", scalar->bytesRequired()); } else { - builder->appendFormat("%s.%s = ", keyname.c_str(), fieldName.c_str()); + builder->appendFormat("%v.%v = ", keyname, fieldName); if (isKeyBigEndian == "NETWORK" && isDefnBigEndian == "HOST") - builder->appendFormat("%s(", swap.c_str()); + builder->appendFormat("%v(", swap); table->codeGen->visit(c->expression); if (isKeyBigEndian == "NETWORK" && isDefnBigEndian == "HOST") builder->append(")"); } @@ -2269,6 +2410,8 @@ void DeparserHdrEmitTranslatorPNA::emitField(EBPF::CodeBuilder *builder, cstring unsigned widthToEmit = et->widthInBits(); unsigned emitSize = 0; cstring swap = ""_cs, msgStr; + auto tcTarget = dynamic_cast(builder->target); + bool isPrimitive = tcTarget->isPrimitiveByteAligned(widthToEmit); if (widthToEmit <= 64) { if (program->options.emitTraceMessages) { @@ -2305,14 +2448,29 @@ void DeparserHdrEmitTranslatorPNA::emitField(EBPF::CodeBuilder *builder, cstring widthToEmit < 8 ? (emitSize - alignment - widthToEmit) : (emitSize - widthToEmit); if (!swap.isNullOrEmpty() && !noEndiannessConversion) { - builder->emitIndent(); - visit(hdrExpr); - builder->appendFormat(".%v = %v(", field, swap); - visit(hdrExpr); - builder->appendFormat(".%v", field); - if (shift != 0) builder->appendFormat(" << %d", shift); - builder->append(")"); - builder->endOfStatement(true); + if (!isPrimitive) { + builder->emitIndent(); + cstring storePrimitive = + widthToEmit < 32 ? "storePrimitive32"_cs : "storePrimitive64"_cs; + cstring getPrimitive = widthToEmit < 32 ? "getPrimitive32"_cs : "getPrimitive64"_cs; + builder->appendFormat("%v((u8 *)&", storePrimitive); + visit(hdrExpr); + builder->appendFormat(".%v, %d, (%v(%v(", field, widthToEmit, swap, getPrimitive); + visit(hdrExpr); + builder->appendFormat(".%v, %d)", field, widthToEmit); + if (shift != 0) builder->appendFormat(" << %d", shift); + builder->append(")))"); + builder->endOfStatement(true); + } else { + builder->emitIndent(); + visit(hdrExpr); + builder->appendFormat(".%v = %v(", field, swap); + visit(hdrExpr); + builder->appendFormat(".%v", field); + if (shift != 0) builder->appendFormat(" << %d", shift); + builder->append(")"); + builder->endOfStatement(true); + } } unsigned bitsInFirstByte = widthToEmit % 8; if (bitsInFirstByte == 0) bitsInFirstByte = 8; diff --git a/backends/tc/ebpfCodeGen.h b/backends/tc/ebpfCodeGen.h index 44b94629202..1b9e08065fb 100644 --- a/backends/tc/ebpfCodeGen.h +++ b/backends/tc/ebpfCodeGen.h @@ -105,6 +105,7 @@ class PNAArchTC : public PNAEbpfGenerator { void emitParser(EBPF::CodeBuilder *builder) const override; void emitHeader(EBPF::CodeBuilder *builder) const override; void emitInstances(EBPF::CodeBuilder *builder) const override; + void emitGlobalFunctions(EBPF::CodeBuilder *builder) const; }; class TCIngressPipelinePNA : public EBPF::TCIngressPipeline { @@ -133,6 +134,7 @@ class PnaStateTranslationVisitor : public EBPF::PsaStateTranslationVisitor { void compileExtractField(const IR::Expression *expr, const IR::StructField *field, unsigned hdrOffsetBits, EBPF::EBPFType *type) override; void compileLookahead(const IR::Expression *destination) override; + bool preorder(const IR::SelectCase *selectCase) override; }; class EBPFPnaParser : public EBPF::EBPFPsaParser { diff --git a/testdata/p4tc_samples_outputs/add_entry_1_example_control_blocks.c b/testdata/p4tc_samples_outputs/add_entry_1_example_control_blocks.c index 69860b00f75..58fd9b1eddc 100644 --- a/testdata/p4tc_samples_outputs/add_entry_1_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/add_entry_1_example_control_blocks.c @@ -26,8 +26,8 @@ struct __attribute__((__packed__)) MainControlImpl_ipv4_tbl_1_value { struct { } MainControlImpl_next_hop; struct __attribute__((__packed__)) { - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } MainControlImpl_send_nh; struct { } MainControlImpl_dflt_route_drop; @@ -93,8 +93,8 @@ if (/* hdr->ipv4.isValid() */ /* add_entry(""send_nh"", {hdr->ethernet.dstAddr, hdr->ethernet.srcAddr}, 2) */ struct p4tc_table_entry_act_bpf update_act_bpf = {}; struct MainControlImpl_ipv4_tbl_1_value *update_act_bpf_val = (struct MainControlImpl_ipv4_tbl_1_value*) &update_act_bpf; - update_act_bpf_val->u.MainControlImpl_send_nh.dmac = hdr->ethernet.dstAddr; - update_act_bpf_val->u.MainControlImpl_send_nh.smac = hdr->ethernet.srcAddr; + storePrimitive64((u8 *)&update_act_bpf_val->u.MainControlImpl_send_nh.dmac, 48, (getPrimitive64((u8 *)hdr->ethernet.dstAddr, 48))); + storePrimitive64((u8 *)&update_act_bpf_val->u.MainControlImpl_send_nh.smac, 48, (ntohll(getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48) << 16))); update_act_bpf_val->action = MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_SEND_NH; /* construct key */ @@ -114,8 +114,8 @@ if (/* hdr->ipv4.isValid() */ break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_SEND_NH: { - hdr->ethernet.srcAddr = bpf_cpu_to_be64(value->u.MainControlImpl_send_nh.smac); - hdr->ethernet.dstAddr = ntohll(value->u.MainControlImpl_send_nh.dmac << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (bpf_cpu_to_be64(getPrimitive64((u8 *)value->u.MainControlImpl_send_nh.smac, 48)))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (ntohll(getPrimitive64((u8 *)value->u.MainControlImpl_send_nh.dmac, 48) << 16))); } break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_DFLT_ROUTE_DROP: @@ -169,7 +169,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/add_entry_1_example_parser.c b/testdata/p4tc_samples_outputs/add_entry_1_example_parser.c index 0b1c93f47e3..a76620cd9d2 100644 --- a/testdata/p4tc_samples_outputs/add_entry_1_example_parser.c +++ b/testdata/p4tc_samples_outputs/add_entry_1_example_parser.c @@ -85,7 +85,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; __builtin_memcpy(&hdr->ethernet.srcAddr, pkt + BYTES(ebpf_packetOffsetInBits), 6); diff --git a/testdata/p4tc_samples_outputs/add_entry_1_example_parser.h b/testdata/p4tc_samples_outputs/add_entry_1_example_parser.h index 6e42437522c..d4242e49d66 100644 --- a/testdata/p4tc_samples_outputs/add_entry_1_example_parser.h +++ b/testdata/p4tc_samples_outputs/add_entry_1_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -39,8 +39,8 @@ struct headers_t { struct ipv4_t ipv4; /* ipv4_t */ }; struct tuple_0 { - u64 f0; /* bit<48> */ - u64 f1; /* bit<48> */ + u8 f0[6]; /* bit<48> */ + u8 f1[6]; /* bit<48> */ }; struct hdr_md { @@ -65,3 +65,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/add_entry_3_example_control_blocks.c b/testdata/p4tc_samples_outputs/add_entry_3_example_control_blocks.c index fb44998d93c..37f83d2be86 100644 --- a/testdata/p4tc_samples_outputs/add_entry_3_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/add_entry_3_example_control_blocks.c @@ -26,8 +26,8 @@ struct __attribute__((__packed__)) MainControlImpl_ipv4_tbl_1_value { struct { } MainControlImpl_next_hop; struct __attribute__((__packed__)) { - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } MainControlImpl_send_nh; struct { } MainControlImpl_dflt_route_drop; @@ -93,8 +93,8 @@ if (/* hdr->ipv4.isValid() */ /* add_entry(""send_nh"", {hdr->ethernet.dstAddr, hdr->ethernet.srcAddr}, 2) */ struct p4tc_table_entry_act_bpf update_act_bpf = {}; struct MainControlImpl_ipv4_tbl_1_value *update_act_bpf_val = (struct MainControlImpl_ipv4_tbl_1_value*) &update_act_bpf; - update_act_bpf_val->u.MainControlImpl_send_nh.dmac = hdr->ethernet.dstAddr; - update_act_bpf_val->u.MainControlImpl_send_nh.smac = hdr->ethernet.srcAddr; + storePrimitive64((u8 *)&update_act_bpf_val->u.MainControlImpl_send_nh.dmac, 48, (getPrimitive64((u8 *)hdr->ethernet.dstAddr, 48))); + storePrimitive64((u8 *)&update_act_bpf_val->u.MainControlImpl_send_nh.smac, 48, (ntohll(getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48) << 16))); update_act_bpf_val->action = MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_SEND_NH; /* construct key */ @@ -114,8 +114,8 @@ if (/* hdr->ipv4.isValid() */ break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_SEND_NH: { - hdr->ethernet.srcAddr = bpf_cpu_to_be64(value->u.MainControlImpl_send_nh.smac); - hdr->ethernet.dstAddr = ntohll(value->u.MainControlImpl_send_nh.dmac << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (bpf_cpu_to_be64(getPrimitive64((u8 *)value->u.MainControlImpl_send_nh.smac, 48)))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (ntohll(getPrimitive64((u8 *)value->u.MainControlImpl_send_nh.dmac, 48) << 16))); } break; case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_DFLT_ROUTE_DROP: @@ -169,7 +169,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/add_entry_3_example_parser.c b/testdata/p4tc_samples_outputs/add_entry_3_example_parser.c index 84e09a9ebba..731f3573fff 100644 --- a/testdata/p4tc_samples_outputs/add_entry_3_example_parser.c +++ b/testdata/p4tc_samples_outputs/add_entry_3_example_parser.c @@ -85,7 +85,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; __builtin_memcpy(&hdr->ethernet.srcAddr, pkt + BYTES(ebpf_packetOffsetInBits), 6); diff --git a/testdata/p4tc_samples_outputs/add_entry_3_example_parser.h b/testdata/p4tc_samples_outputs/add_entry_3_example_parser.h index 6e42437522c..d4242e49d66 100644 --- a/testdata/p4tc_samples_outputs/add_entry_3_example_parser.h +++ b/testdata/p4tc_samples_outputs/add_entry_3_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -39,8 +39,8 @@ struct headers_t { struct ipv4_t ipv4; /* ipv4_t */ }; struct tuple_0 { - u64 f0; /* bit<48> */ - u64 f1; /* bit<48> */ + u8 f0[6]; /* bit<48> */ + u8 f1[6]; /* bit<48> */ }; struct hdr_md { @@ -65,3 +65,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/add_entry_example_parser.h b/testdata/p4tc_samples_outputs/add_entry_example_parser.h index 929d5e054a7..48c6bd08576 100644 --- a/testdata/p4tc_samples_outputs/add_entry_example_parser.h +++ b/testdata/p4tc_samples_outputs/add_entry_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -65,3 +65,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/calculator_control_blocks.c b/testdata/p4tc_samples_outputs/calculator_control_blocks.c index 782ce636932..009956aa589 100644 --- a/testdata/p4tc_samples_outputs/calculator_control_blocks.c +++ b/testdata/p4tc_samples_outputs/calculator_control_blocks.c @@ -64,7 +64,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr, meta = &(hdrMd->cpumap_usermeta); { u8 hit; - u64 tmp_5 = 0; + u8 tmp_5[6] = {0}; { if (/* hdr->p4calc.isValid() */ hdr->p4calc.ebpf_valid) { @@ -97,9 +97,9 @@ if (/* hdr->p4calc.isValid() */ case MAINCONTROLIMPL_CALCULATE_ACT_MAINCONTROLIMPL_OPERATION_ADD: { hdr->p4calc.res = (hdr->p4calc.operand_a + hdr->p4calc.operand_b); - tmp_5 = hdr->ethernet.dstAddr; - hdr->ethernet.dstAddr = hdr->ethernet.srcAddr; - hdr->ethernet.srcAddr = tmp_5; + storePrimitive64((u8 *)&tmp_5, 48, (getPrimitive64((u8 *)hdr->ethernet.dstAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)tmp_5, 48))); /* send_to_port(skb->ifindex) */ compiler_meta__->drop = false; send_to_port(skb->ifindex); @@ -108,9 +108,9 @@ if (/* hdr->p4calc.isValid() */ case MAINCONTROLIMPL_CALCULATE_ACT_MAINCONTROLIMPL_OPERATION_SUB: { hdr->p4calc.res = (hdr->p4calc.operand_a - hdr->p4calc.operand_b); - tmp_5 = hdr->ethernet.dstAddr; - hdr->ethernet.dstAddr = hdr->ethernet.srcAddr; - hdr->ethernet.srcAddr = tmp_5; + storePrimitive64((u8 *)&tmp_5, 48, (getPrimitive64((u8 *)hdr->ethernet.dstAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)tmp_5, 48))); /* send_to_port(skb->ifindex) */ compiler_meta__->drop = false; send_to_port(skb->ifindex); @@ -119,9 +119,9 @@ if (/* hdr->p4calc.isValid() */ case MAINCONTROLIMPL_CALCULATE_ACT_MAINCONTROLIMPL_OPERATION_AND: { hdr->p4calc.res = (hdr->p4calc.operand_a & hdr->p4calc.operand_b); - tmp_5 = hdr->ethernet.dstAddr; - hdr->ethernet.dstAddr = hdr->ethernet.srcAddr; - hdr->ethernet.srcAddr = tmp_5; + storePrimitive64((u8 *)&tmp_5, 48, (getPrimitive64((u8 *)hdr->ethernet.dstAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)tmp_5, 48))); /* send_to_port(skb->ifindex) */ compiler_meta__->drop = false; send_to_port(skb->ifindex); @@ -130,9 +130,9 @@ if (/* hdr->p4calc.isValid() */ case MAINCONTROLIMPL_CALCULATE_ACT_MAINCONTROLIMPL_OPERATION_OR: { hdr->p4calc.res = (hdr->p4calc.operand_a | hdr->p4calc.operand_b); - tmp_5 = hdr->ethernet.dstAddr; - hdr->ethernet.dstAddr = hdr->ethernet.srcAddr; - hdr->ethernet.srcAddr = tmp_5; + storePrimitive64((u8 *)&tmp_5, 48, (getPrimitive64((u8 *)hdr->ethernet.dstAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)tmp_5, 48))); /* send_to_port(skb->ifindex) */ compiler_meta__->drop = false; send_to_port(skb->ifindex); @@ -141,9 +141,9 @@ if (/* hdr->p4calc.isValid() */ case MAINCONTROLIMPL_CALCULATE_ACT_MAINCONTROLIMPL_OPERATION_XOR: { hdr->p4calc.res = (hdr->p4calc.operand_a ^ hdr->p4calc.operand_b); - tmp_5 = hdr->ethernet.dstAddr; - hdr->ethernet.dstAddr = hdr->ethernet.srcAddr; - hdr->ethernet.srcAddr = tmp_5; + storePrimitive64((u8 *)&tmp_5, 48, (getPrimitive64((u8 *)hdr->ethernet.dstAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48))); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)tmp_5, 48))); /* send_to_port(skb->ifindex) */ compiler_meta__->drop = false; send_to_port(skb->ifindex); @@ -207,7 +207,7 @@ if (/* hdr->p4calc.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -222,7 +222,7 @@ if (/* hdr->p4calc.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/calculator_parser.c b/testdata/p4tc_samples_outputs/calculator_parser.c index a9623807c5c..d1b52313bbb 100644 --- a/testdata/p4tc_samples_outputs/calculator_parser.c +++ b/testdata/p4tc_samples_outputs/calculator_parser.c @@ -140,10 +140,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h hdr_start = hdr_start_save; ebpf_packetOffsetInBits = ebpf_packetOffsetInBits_save; } - u32 select_0; - select_0 = (((((u32)(((u16)tmp_0.p << 8) | ((u16)tmp_2.four & 0xff)) << 8) & ((1 << 24) - 1)) | (((u32)tmp_4.ver & 0xff) & ((1 << 24) - 1))) & ((1 << 24) - 1)); + u8 select_0[3]; + storePrimitive32((u8 *)&select_0, 24, ((((((u32)(((u16)tmp_0.p << 8) | ((u16)tmp_2.four & 0xff)) << 8) & ((1 << 24) - 1)) | (((u32)tmp_4.ver & 0xff) & ((1 << 24) - 1))) & ((1 << 24) - 1)))); if (select_0 == 0x503401)goto parse_p4calc; - if ((select_0 & 0x0) == (0x0 & 0x0))goto accept; + if ((getPrimitive32((u8 *)select_0, 24) & 0x0) == (0x0 & 0x0))goto accept; else goto reject; } parse_p4calc: { @@ -188,10 +188,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/calculator_parser.h b/testdata/p4tc_samples_outputs/calculator_parser.h index 1645fd45158..aa23e059c23 100644 --- a/testdata/p4tc_samples_outputs/calculator_parser.h +++ b/testdata/p4tc_samples_outputs/calculator_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -56,3 +56,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/checksum_control_blocks.c b/testdata/p4tc_samples_outputs/checksum_control_blocks.c index 345bf2761ca..096b60a26ed 100644 --- a/testdata/p4tc_samples_outputs/checksum_control_blocks.c +++ b/testdata/p4tc_samples_outputs/checksum_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -84,8 +84,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/checksum_parser.h b/testdata/p4tc_samples_outputs/checksum_parser.h index 300b4de819a..ad5071dbb3b 100644 --- a/testdata/p4tc_samples_outputs/checksum_parser.h +++ b/testdata/p4tc_samples_outputs/checksum_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -79,3 +79,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/const_entries_range_mask_parser.h b/testdata/p4tc_samples_outputs/const_entries_range_mask_parser.h index 2f2e0fa6123..f0d659de619 100644 --- a/testdata/p4tc_samples_outputs/const_entries_range_mask_parser.h +++ b/testdata/p4tc_samples_outputs/const_entries_range_mask_parser.h @@ -47,3 +47,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/default_action_example_01_control_blocks.c b/testdata/p4tc_samples_outputs/default_action_example_01_control_blocks.c index d7701be5daf..ee4d985d7a1 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/default_action_example_01_control_blocks.c @@ -197,7 +197,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -212,7 +212,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/default_action_example_01_parser.c b/testdata/p4tc_samples_outputs/default_action_example_01_parser.c index cd9f245e208..a8054b23906 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_01_parser.c +++ b/testdata/p4tc_samples_outputs/default_action_example_01_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/default_action_example_01_parser.h b/testdata/p4tc_samples_outputs/default_action_example_01_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/default_action_example_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/default_action_example_control_blocks.c b/testdata/p4tc_samples_outputs/default_action_example_control_blocks.c index ccef7178c74..b897da1af21 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/default_action_example_control_blocks.c @@ -217,7 +217,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -232,7 +232,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/default_action_example_parser.c b/testdata/p4tc_samples_outputs/default_action_example_parser.c index 108a626cb77..660a2f9fc3d 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_parser.c +++ b/testdata/p4tc_samples_outputs/default_action_example_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/default_action_example_parser.h b/testdata/p4tc_samples_outputs/default_action_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_parser.h +++ b/testdata/p4tc_samples_outputs/default_action_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/default_action_with_param_01_control_blocks.c b/testdata/p4tc_samples_outputs/default_action_with_param_01_control_blocks.c index 58467d1d1d5..f3766e1fbcf 100644 --- a/testdata/p4tc_samples_outputs/default_action_with_param_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/default_action_with_param_01_control_blocks.c @@ -217,7 +217,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr, return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -232,7 +232,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr, write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.c b/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.c index 5423435e2eb..80018a64ecc 100644 --- a/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.c +++ b/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.h b/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.h +++ b/testdata/p4tc_samples_outputs/default_action_with_param_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/default_action_with_param_control_blocks.c b/testdata/p4tc_samples_outputs/default_action_with_param_control_blocks.c index e197e400974..6b9366c54d8 100644 --- a/testdata/p4tc_samples_outputs/default_action_with_param_control_blocks.c +++ b/testdata/p4tc_samples_outputs/default_action_with_param_control_blocks.c @@ -217,7 +217,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -232,7 +232,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/default_action_with_param_parser.c b/testdata/p4tc_samples_outputs/default_action_with_param_parser.c index 7c7b9b1bf32..09f075d5197 100644 --- a/testdata/p4tc_samples_outputs/default_action_with_param_parser.c +++ b/testdata/p4tc_samples_outputs/default_action_with_param_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/default_action_with_param_parser.h b/testdata/p4tc_samples_outputs/default_action_with_param_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/default_action_with_param_parser.h +++ b/testdata/p4tc_samples_outputs/default_action_with_param_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/default_hit_const_example_control_blocks.c b/testdata/p4tc_samples_outputs/default_hit_const_example_control_blocks.c index e86861498d2..aef27725b0c 100644 --- a/testdata/p4tc_samples_outputs/default_hit_const_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/default_hit_const_example_control_blocks.c @@ -142,7 +142,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->eth.dstAddr = htonll(hdr->eth.dstAddr << 16); + storePrimitive64((u8 *)&hdr->eth.dstAddr, 48, (htonll(getPrimitive64(hdr->eth.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->eth.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->eth.dstAddr))[1]; @@ -157,7 +157,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->eth.srcAddr = htonll(hdr->eth.srcAddr << 16); + storePrimitive64((u8 *)&hdr->eth.srcAddr, 48, (htonll(getPrimitive64(hdr->eth.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->eth.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->eth.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/default_hit_const_example_parser.c b/testdata/p4tc_samples_outputs/default_hit_const_example_parser.c index 0547d47bdb5..36b8f84f04d 100644 --- a/testdata/p4tc_samples_outputs/default_hit_const_example_parser.c +++ b/testdata/p4tc_samples_outputs/default_hit_const_example_parser.c @@ -133,10 +133,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->eth.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->eth.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->eth.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->eth.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->eth.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/default_hit_const_example_parser.h b/testdata/p4tc_samples_outputs/default_hit_const_example_parser.h index 352d0815e9b..9967a201028 100644 --- a/testdata/p4tc_samples_outputs/default_hit_const_example_parser.h +++ b/testdata/p4tc_samples_outputs/default_hit_const_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -75,3 +75,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/digest_01_control_blocks.c b/testdata/p4tc_samples_outputs/digest_01_control_blocks.c index 940cc86b8b2..7114942cc17 100644 --- a/testdata/p4tc_samples_outputs/digest_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/digest_01_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port; - u64 srcMac; - u64 dstMac; + u8 srcMac[6]; + u8 dstMac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -87,8 +87,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.srcMac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dstMac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.srcMac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dstMac, 48))); meta->ingress_port = skb->ifindex; meta->send_digest = true; /* send_to_port(value->u.ingress_send_nh.port) */ diff --git a/testdata/p4tc_samples_outputs/digest_01_parser.h b/testdata/p4tc_samples_outputs/digest_01_parser.h index 6cb04fcdf9a..faf63bb8bda 100644 --- a/testdata/p4tc_samples_outputs/digest_01_parser.h +++ b/testdata/p4tc_samples_outputs/digest_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -41,7 +41,7 @@ struct my_ingress_metadata_t { u8 send_digest; /* bool */ }; struct mac_learn_digest_t { - u64 srcAddr; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u32 ingress_port; /* PortId_t */ }; @@ -67,3 +67,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/digest_control_blocks.c b/testdata/p4tc_samples_outputs/digest_control_blocks.c index 21bd4337217..f5d6a306b9a 100644 --- a/testdata/p4tc_samples_outputs/digest_control_blocks.c +++ b/testdata/p4tc_samples_outputs/digest_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port; - u64 srcMac; - u64 dstMac; + u8 srcMac[6]; + u8 dstMac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -87,8 +87,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.srcMac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dstMac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.srcMac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dstMac, 48))); meta->ingress_port = skb->ifindex; meta->send_digest = true; /* send_to_port(value->u.ingress_send_nh.port) */ @@ -120,7 +120,7 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head __builtin_memset((void *) &mac_learn_digest_0, 0, sizeof(struct mac_learn_digest_t )); { if (meta->send_digest) { - mac_learn_digest_0.srcAddr = hdr->ethernet.srcAddr; + storePrimitive64((u8 *)&mac_learn_digest_0.srcAddr, 48, (getPrimitive64((u8 *)hdr->ethernet.srcAddr, 48))); mac_learn_digest_0.ingress_port = meta->ingress_port; /* digest_inst_0.pack(mac_learn_digest_0) */ diff --git a/testdata/p4tc_samples_outputs/digest_parser.h b/testdata/p4tc_samples_outputs/digest_parser.h index 6cb04fcdf9a..faf63bb8bda 100644 --- a/testdata/p4tc_samples_outputs/digest_parser.h +++ b/testdata/p4tc_samples_outputs/digest_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -41,7 +41,7 @@ struct my_ingress_metadata_t { u8 send_digest; /* bool */ }; struct mac_learn_digest_t { - u64 srcAddr; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u32 ingress_port; /* PortId_t */ }; @@ -67,3 +67,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/digest_parser_meta_control_blocks.c b/testdata/p4tc_samples_outputs/digest_parser_meta_control_blocks.c index 87420dcad36..ef030146215 100644 --- a/testdata/p4tc_samples_outputs/digest_parser_meta_control_blocks.c +++ b/testdata/p4tc_samples_outputs/digest_parser_meta_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port; - u64 srcMac; - u64 dstMac; + u8 srcMac[6]; + u8 dstMac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -86,8 +86,8 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.srcMac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dstMac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.srcMac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dstMac, 48))); /* send_to_port(value->u.ingress_send_nh.port) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port); diff --git a/testdata/p4tc_samples_outputs/digest_parser_meta_parser.h b/testdata/p4tc_samples_outputs/digest_parser_meta_parser.h index 3f9ca35c9c7..17ecd42515e 100644 --- a/testdata/p4tc_samples_outputs/digest_parser_meta_parser.h +++ b/testdata/p4tc_samples_outputs/digest_parser_meta_parser.h @@ -15,8 +15,8 @@ struct my_ingress_metadata_t { u32 ingress_port; /* PortId_t */ }; struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -66,3 +66,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/direct_counter_example_control_blocks.c b/testdata/p4tc_samples_outputs/direct_counter_example_control_blocks.c index 81f840dfb8e..258ae007899 100644 --- a/testdata/p4tc_samples_outputs/direct_counter_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/direct_counter_example_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -87,8 +87,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/direct_counter_example_parser.h b/testdata/p4tc_samples_outputs/direct_counter_example_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/direct_counter_example_parser.h +++ b/testdata/p4tc_samples_outputs/direct_counter_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/direct_meter_color_parser.h b/testdata/p4tc_samples_outputs/direct_meter_color_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/direct_meter_color_parser.h +++ b/testdata/p4tc_samples_outputs/direct_meter_color_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/direct_meter_parser.h b/testdata/p4tc_samples_outputs/direct_meter_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/direct_meter_parser.h +++ b/testdata/p4tc_samples_outputs/direct_meter_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/drop_packet_example_control_blocks.c b/testdata/p4tc_samples_outputs/drop_packet_example_control_blocks.c index 5aa0fce713c..52f78e00c0f 100644 --- a/testdata/p4tc_samples_outputs/drop_packet_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/drop_packet_example_control_blocks.c @@ -140,7 +140,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -155,7 +155,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/drop_packet_example_parser.c b/testdata/p4tc_samples_outputs/drop_packet_example_parser.c index dc11f5f8b34..90e4adfe596 100644 --- a/testdata/p4tc_samples_outputs/drop_packet_example_parser.c +++ b/testdata/p4tc_samples_outputs/drop_packet_example_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/drop_packet_example_parser.h b/testdata/p4tc_samples_outputs/drop_packet_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/drop_packet_example_parser.h +++ b/testdata/p4tc_samples_outputs/drop_packet_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/global_action_example_01_control_blocks.c b/testdata/p4tc_samples_outputs/global_action_example_01_control_blocks.c index 9627bdb0090..63e2b2968e0 100644 --- a/testdata/p4tc_samples_outputs/global_action_example_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/global_action_example_01_control_blocks.c @@ -23,7 +23,7 @@ struct __attribute__((__packed__)) ingress_nh_table2_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; + u8 dmac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -47,8 +47,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } _send_nh; struct { } ingress_drop; @@ -111,8 +111,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head /* send_to_port(value->u._send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u._send_nh.port_id); - hdr->ethernet.srcAddr = value->u._send_nh.smac; - hdr->ethernet.dstAddr = value->u._send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u._send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u._send_nh.dmac, 48))); } break; case INGRESS_NH_TABLE_ACT_INGRESS_DROP: @@ -158,7 +158,7 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE2_ACT_INGRESS_SEND_NH: { - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/global_action_example_01_parser.h b/testdata/p4tc_samples_outputs/global_action_example_01_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/global_action_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/global_action_example_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/global_action_example_02_control_blocks.c b/testdata/p4tc_samples_outputs/global_action_example_02_control_blocks.c index 7cb9c3452ee..15f10d86dcc 100644 --- a/testdata/p4tc_samples_outputs/global_action_example_02_control_blocks.c +++ b/testdata/p4tc_samples_outputs/global_action_example_02_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table2_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -48,8 +48,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } _drop; @@ -109,8 +109,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); @@ -159,8 +159,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE2_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/global_action_example_02_parser.h b/testdata/p4tc_samples_outputs/global_action_example_02_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/global_action_example_02_parser.h +++ b/testdata/p4tc_samples_outputs/global_action_example_02_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/hash1_parser.h b/testdata/p4tc_samples_outputs/hash1_parser.h index 94841425a8e..9f38b88cb31 100644 --- a/testdata/p4tc_samples_outputs/hash1_parser.h +++ b/testdata/p4tc_samples_outputs/hash1_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -78,3 +78,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/hash_parser.h b/testdata/p4tc_samples_outputs/hash_parser.h index 893d1608192..43bef15c0c8 100644 --- a/testdata/p4tc_samples_outputs/hash_parser.h +++ b/testdata/p4tc_samples_outputs/hash_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -78,3 +78,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/indirect_counter_01_example_control_blocks.c b/testdata/p4tc_samples_outputs/indirect_counter_01_example_control_blocks.c index 9ad5fd5c2ee..145529aed8b 100644 --- a/testdata/p4tc_samples_outputs/indirect_counter_01_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/indirect_counter_01_example_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -90,8 +90,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/indirect_counter_01_example_parser.h b/testdata/p4tc_samples_outputs/indirect_counter_01_example_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/indirect_counter_01_example_parser.h +++ b/testdata/p4tc_samples_outputs/indirect_counter_01_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c b/testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c index 66f01311a3e..594cdd4dbbf 100644 --- a/testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c @@ -28,7 +28,7 @@ struct __attribute__((__packed__)) ingress_fwd_table_value { u32 port; } ingress_set_ipip_csum; struct __attribute__((__packed__)) { - u64 dmac; + u8 dmac[6]; u32 port; } ingress_set_nh; struct { @@ -101,7 +101,7 @@ if (/* hdr->outer.isValid() */ break; case INGRESS_FWD_TABLE_ACT_INGRESS_SET_NH: { - hdr->ethernet.dstAddr = value->u.ingress_set_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_set_nh.dmac, 48))); /* send_to_port(value->u.ingress_set_nh.port) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_set_nh.port); diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01_parser.h b/testdata/p4tc_samples_outputs/internetchecksum_01_parser.h index aa9b19c0bf4..9ee6beb089d 100644 --- a/testdata/p4tc_samples_outputs/internetchecksum_01_parser.h +++ b/testdata/p4tc_samples_outputs/internetchecksum_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -85,3 +85,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/ipip_control_blocks.c b/testdata/p4tc_samples_outputs/ipip_control_blocks.c index 99680833239..95a96a4d855 100644 --- a/testdata/p4tc_samples_outputs/ipip_control_blocks.c +++ b/testdata/p4tc_samples_outputs/ipip_control_blocks.c @@ -28,7 +28,7 @@ struct __attribute__((__packed__)) Main_fwd_table_value { u32 port; } Main_set_ipip; struct __attribute__((__packed__)) { - u64 dmac; + u8 dmac[6]; u32 port; } Main_set_nh; struct { @@ -101,7 +101,7 @@ if (/* hdr->outer.isValid() */ break; case MAIN_FWD_TABLE_ACT_MAIN_SET_NH: { - hdr->ethernet.dstAddr = value->u.Main_set_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.Main_set_nh.dmac, 48))); /* send_to_port(value->u.Main_set_nh.port) */ compiler_meta__->drop = false; send_to_port(value->u.Main_set_nh.port); diff --git a/testdata/p4tc_samples_outputs/ipip_parser.h b/testdata/p4tc_samples_outputs/ipip_parser.h index 48b48ac4944..d4752592ae8 100644 --- a/testdata/p4tc_samples_outputs/ipip_parser.h +++ b/testdata/p4tc_samples_outputs/ipip_parser.h @@ -17,8 +17,8 @@ struct metadata_t { u8 push; /* bool */ }; struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -65,3 +65,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/is_host_port_control_blocks.c b/testdata/p4tc_samples_outputs/is_host_port_control_blocks.c index ffff2bafb1a..00264becd6f 100644 --- a/testdata/p4tc_samples_outputs/is_host_port_control_blocks.c +++ b/testdata/p4tc_samples_outputs/is_host_port_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -95,8 +95,8 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/is_host_port_parser.h b/testdata/p4tc_samples_outputs/is_host_port_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/is_host_port_parser.h +++ b/testdata/p4tc_samples_outputs/is_host_port_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/is_net_port_control_blocks.c b/testdata/p4tc_samples_outputs/is_net_port_control_blocks.c index 5b44f451af2..8ac1a7020a9 100644 --- a/testdata/p4tc_samples_outputs/is_net_port_control_blocks.c +++ b/testdata/p4tc_samples_outputs/is_net_port_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -95,8 +95,8 @@ if (/* hdr->ipv4.isValid() */ switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/is_net_port_parser.h b/testdata/p4tc_samples_outputs/is_net_port_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/is_net_port_parser.h +++ b/testdata/p4tc_samples_outputs/is_net_port_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/matchtype_control_blocks.c b/testdata/p4tc_samples_outputs/matchtype_control_blocks.c index ab3253b2dbb..203ee40df20 100644 --- a/testdata/p4tc_samples_outputs/matchtype_control_blocks.c +++ b/testdata/p4tc_samples_outputs/matchtype_control_blocks.c @@ -365,7 +365,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -380,7 +380,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/matchtype_parser.c b/testdata/p4tc_samples_outputs/matchtype_parser.c index 6bca9c633c7..66ec6a2885c 100644 --- a/testdata/p4tc_samples_outputs/matchtype_parser.c +++ b/testdata/p4tc_samples_outputs/matchtype_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/matchtype_parser.h b/testdata/p4tc_samples_outputs/matchtype_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/matchtype_parser.h +++ b/testdata/p4tc_samples_outputs/matchtype_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/meter_color_parser.h b/testdata/p4tc_samples_outputs/meter_color_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/meter_color_parser.h +++ b/testdata/p4tc_samples_outputs/meter_color_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/meter_parser.h b/testdata/p4tc_samples_outputs/meter_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/meter_parser.h +++ b/testdata/p4tc_samples_outputs/meter_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/mix_matchtype_example_control_blocks.c b/testdata/p4tc_samples_outputs/mix_matchtype_example_control_blocks.c index 8b0c6015efa..645ce373a28 100644 --- a/testdata/p4tc_samples_outputs/mix_matchtype_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/mix_matchtype_example_control_blocks.c @@ -371,7 +371,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -386,7 +386,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.c b/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.c index 0e2e8079452..805bbec82af 100644 --- a/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.c +++ b/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h b/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h +++ b/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/multiple_tables_example_01_control_blocks.c b/testdata/p4tc_samples_outputs/multiple_tables_example_01_control_blocks.c index 3209d563f68..4ab12aa4f28 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_01_control_blocks.c @@ -622,7 +622,7 @@ if (hdr->ipv4.protocol != 4 || (hdr->tcp.srcPort <= 3)) { return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -637,7 +637,7 @@ if (hdr->ipv4.protocol != 4 || (hdr->tcp.srcPort <= 3)) { write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.c b/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.c index d765938d0c5..a27bdf43ff7 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.c +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.c @@ -133,10 +133,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.h b/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.h index 0bb6fe0e1ed..089a96afca3 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -75,3 +75,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/multiple_tables_example_02_control_blocks.c b/testdata/p4tc_samples_outputs/multiple_tables_example_02_control_blocks.c index f14364a20ce..8279e20115d 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_02_control_blocks.c +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_02_control_blocks.c @@ -622,7 +622,7 @@ if (hdr->ipv4.protocol == 6 || ((hdr->ipv4.version > 1) && (hdr->ipv4.ihl <= 2)) return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -637,7 +637,7 @@ if (hdr->ipv4.protocol == 6 || ((hdr->ipv4.version > 1) && (hdr->ipv4.ihl <= 2)) write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.c b/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.c index 866917aa245..c070f2d40e9 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.c +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.c @@ -133,10 +133,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.h b/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.h index 0bb6fe0e1ed..089a96afca3 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.h +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -75,3 +75,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/name_annotation_example_control_blocks.c b/testdata/p4tc_samples_outputs/name_annotation_example_control_blocks.c index ec20ae1b6f8..68aa8d3b4ec 100644 --- a/testdata/p4tc_samples_outputs/name_annotation_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/name_annotation_example_control_blocks.c @@ -215,7 +215,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -230,7 +230,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/name_annotation_example_parser.c b/testdata/p4tc_samples_outputs/name_annotation_example_parser.c index 0733cba3b7d..8f74f215f03 100644 --- a/testdata/p4tc_samples_outputs/name_annotation_example_parser.c +++ b/testdata/p4tc_samples_outputs/name_annotation_example_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/name_annotation_example_parser.h b/testdata/p4tc_samples_outputs/name_annotation_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/name_annotation_example_parser.h +++ b/testdata/p4tc_samples_outputs/name_annotation_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/no_table_example_control_blocks.c b/testdata/p4tc_samples_outputs/no_table_example_control_blocks.c index 1ed4181e435..f8821945db5 100644 --- a/testdata/p4tc_samples_outputs/no_table_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/no_table_example_control_blocks.c @@ -73,7 +73,7 @@ if ((u32)skb->ifindex == 4) { return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -88,7 +88,7 @@ if ((u32)skb->ifindex == 4) { write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/no_table_example_parser.c b/testdata/p4tc_samples_outputs/no_table_example_parser.c index 19bdd105c56..e498f1f9acc 100644 --- a/testdata/p4tc_samples_outputs/no_table_example_parser.c +++ b/testdata/p4tc_samples_outputs/no_table_example_parser.c @@ -108,10 +108,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/no_table_example_parser.h b/testdata/p4tc_samples_outputs/no_table_example_parser.h index 75006eeeca5..f340d5b684f 100644 --- a/testdata/p4tc_samples_outputs/no_table_example_parser.h +++ b/testdata/p4tc_samples_outputs/no_table_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -69,3 +69,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/noaction_example_01_control_blocks.c b/testdata/p4tc_samples_outputs/noaction_example_01_control_blocks.c index d2d7e226cee..34dd804db70 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/noaction_example_01_control_blocks.c @@ -215,7 +215,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -230,7 +230,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/noaction_example_01_parser.c b/testdata/p4tc_samples_outputs/noaction_example_01_parser.c index 4e0c2a54e70..e14af58ed1a 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_01_parser.c +++ b/testdata/p4tc_samples_outputs/noaction_example_01_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/noaction_example_01_parser.h b/testdata/p4tc_samples_outputs/noaction_example_01_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/noaction_example_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/noaction_example_02_control_blocks.c b/testdata/p4tc_samples_outputs/noaction_example_02_control_blocks.c index e4954116271..9a67c51a96a 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_02_control_blocks.c +++ b/testdata/p4tc_samples_outputs/noaction_example_02_control_blocks.c @@ -191,7 +191,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -206,7 +206,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/noaction_example_02_parser.c b/testdata/p4tc_samples_outputs/noaction_example_02_parser.c index 03e9a9fcdac..622a49069b6 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_02_parser.c +++ b/testdata/p4tc_samples_outputs/noaction_example_02_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/noaction_example_02_parser.h b/testdata/p4tc_samples_outputs/noaction_example_02_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_02_parser.h +++ b/testdata/p4tc_samples_outputs/noaction_example_02_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/nummask_annotation_example_control_blocks.c b/testdata/p4tc_samples_outputs/nummask_annotation_example_control_blocks.c index 8371e7fcd8a..66f2442dc6b 100644 --- a/testdata/p4tc_samples_outputs/nummask_annotation_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/nummask_annotation_example_control_blocks.c @@ -138,7 +138,7 @@ if (((u32)skb->ifindex == 2 && /* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->eth.dstAddr = htonll(hdr->eth.dstAddr << 16); + storePrimitive64((u8 *)&hdr->eth.dstAddr, 48, (htonll(getPrimitive64(hdr->eth.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->eth.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->eth.dstAddr))[1]; @@ -153,7 +153,7 @@ if (((u32)skb->ifindex == 2 && /* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->eth.srcAddr = htonll(hdr->eth.srcAddr << 16); + storePrimitive64((u8 *)&hdr->eth.srcAddr, 48, (htonll(getPrimitive64(hdr->eth.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->eth.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->eth.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.c b/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.c index 6f59cc58fd1..278b02b26d9 100644 --- a/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.c +++ b/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.c @@ -133,10 +133,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->eth.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->eth.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->eth.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->eth.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->eth.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h b/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h index 352d0815e9b..9967a201028 100644 --- a/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h +++ b/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -75,3 +75,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/send_to_port_example_control_blocks.c b/testdata/p4tc_samples_outputs/send_to_port_example_control_blocks.c index 7375df90426..1e1649399b5 100644 --- a/testdata/p4tc_samples_outputs/send_to_port_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/send_to_port_example_control_blocks.c @@ -170,7 +170,7 @@ ext_val = *ext_val_ptr; return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -185,7 +185,7 @@ ext_val = *ext_val_ptr; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/send_to_port_example_parser.c b/testdata/p4tc_samples_outputs/send_to_port_example_parser.c index a21b8aeabf5..9d688e6c7b2 100644 --- a/testdata/p4tc_samples_outputs/send_to_port_example_parser.c +++ b/testdata/p4tc_samples_outputs/send_to_port_example_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/send_to_port_example_parser.h b/testdata/p4tc_samples_outputs/send_to_port_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/send_to_port_example_parser.h +++ b/testdata/p4tc_samples_outputs/send_to_port_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/set_entry_timer_example_control_blocks.c b/testdata/p4tc_samples_outputs/set_entry_timer_example_control_blocks.c index 07eebe4dd17..fd785ab1c84 100644 --- a/testdata/p4tc_samples_outputs/set_entry_timer_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/set_entry_timer_example_control_blocks.c @@ -225,7 +225,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -240,7 +240,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.c b/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.c index 72e7fa57bdc..d5d24d429cf 100644 --- a/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.c +++ b/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.h b/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.h +++ b/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/simple_exact_example_control_blocks.c b/testdata/p4tc_samples_outputs/simple_exact_example_control_blocks.c index 5216d83472f..8d9fb52e26c 100644 --- a/testdata/p4tc_samples_outputs/simple_exact_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/simple_exact_example_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -84,8 +84,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/simple_exact_example_parser.h b/testdata/p4tc_samples_outputs/simple_exact_example_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/simple_exact_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_exact_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/simple_extern_example_control_blocks.c b/testdata/p4tc_samples_outputs/simple_extern_example_control_blocks.c index 628bf01fe72..0a8fae669f5 100644 --- a/testdata/p4tc_samples_outputs/simple_extern_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/simple_extern_example_control_blocks.c @@ -27,8 +27,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } ingress_ext_reg; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -135,8 +135,8 @@ ext_val = *ext_val_ptr; break; case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/simple_extern_example_parser.h b/testdata/p4tc_samples_outputs/simple_extern_example_parser.h index 06164768dec..a2783793b7d 100644 --- a/testdata/p4tc_samples_outputs/simple_extern_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_extern_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -67,3 +67,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/simple_lpm_example_control_blocks.c b/testdata/p4tc_samples_outputs/simple_lpm_example_control_blocks.c index 606c218c12b..5d8b32b110d 100644 --- a/testdata/p4tc_samples_outputs/simple_lpm_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/simple_lpm_example_control_blocks.c @@ -23,8 +23,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -84,8 +84,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h b/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/simple_ternary_example_control_blocks.c b/testdata/p4tc_samples_outputs/simple_ternary_example_control_blocks.c index f8bf4947570..b478f5ee36d 100644 --- a/testdata/p4tc_samples_outputs/simple_ternary_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/simple_ternary_example_control_blocks.c @@ -28,8 +28,8 @@ struct __attribute__((__packed__)) ingress_nh_table_value { } _NoAction; struct __attribute__((__packed__)) { u32 port_id; - u64 dmac; - u64 smac; + u8 dmac[6]; + u8 smac[6]; } ingress_send_nh; struct { } ingress_drop; @@ -90,8 +90,8 @@ static __always_inline int process(struct __sk_buff *skb, struct my_ingress_head switch (value->action) { case INGRESS_NH_TABLE_ACT_INGRESS_SEND_NH: { - hdr->ethernet.srcAddr = value->u.ingress_send_nh.smac; - hdr->ethernet.dstAddr = value->u.ingress_send_nh.dmac; + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.smac, 48))); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (getPrimitive64((u8 *)value->u.ingress_send_nh.dmac, 48))); /* send_to_port(value->u.ingress_send_nh.port_id) */ compiler_meta__->drop = false; send_to_port(value->u.ingress_send_nh.port_id); diff --git a/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h b/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h index a4fbecb2270..c99c2dccd46 100644 --- a/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* bit<48> */ - u64 srcAddr; /* bit<48> */ + u8 dstAddr[6]; /* bit<48> */ + u8 srcAddr[6]; /* bit<48> */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/size_param_example_control_blocks.c b/testdata/p4tc_samples_outputs/size_param_example_control_blocks.c index feba76ab744..ef816c97c7a 100644 --- a/testdata/p4tc_samples_outputs/size_param_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/size_param_example_control_blocks.c @@ -215,7 +215,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -230,7 +230,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/size_param_example_parser.c b/testdata/p4tc_samples_outputs/size_param_example_parser.c index 697c1199d51..77edc9c209e 100644 --- a/testdata/p4tc_samples_outputs/size_param_example_parser.c +++ b/testdata/p4tc_samples_outputs/size_param_example_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/size_param_example_parser.h b/testdata/p4tc_samples_outputs/size_param_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/size_param_example_parser.h +++ b/testdata/p4tc_samples_outputs/size_param_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c index d04b12b95e0..95a2018c1fb 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_01_control_blocks.c @@ -235,7 +235,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -250,7 +250,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.c index 16fbf526c82..e68001096eb 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.h index 8f8fb971a53..a174c11e201 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_01_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_02_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_02_control_blocks.c index 6c58d986d30..8e252c05c73 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_02_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_02_control_blocks.c @@ -217,7 +217,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -232,7 +232,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.c index 704339bc654..aced249a714 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_02_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_03_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_03_control_blocks.c index 13052c16716..2547f8631e9 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_03_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_03_control_blocks.c @@ -217,7 +217,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr, return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -232,7 +232,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr, write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.c index dfa2d245d8f..53de2347e4a 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_03_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c index 63e2fb8e6fb..bae3a41c767 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_04_control_blocks.c @@ -229,7 +229,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -244,7 +244,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.c index 10ba238ba22..fd37c7dd418 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.h index 06f3e6e418c..ece731a592a 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_04_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -62,3 +62,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c index b7cd71e6dbb..a9ad8f3b9a2 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_05_control_blocks.c @@ -226,7 +226,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -241,7 +241,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.c index dcb5018eb10..cc7b28c23e3 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.h index 74b1b65a628..1f7bb8949e8 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_05_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -62,3 +62,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c index 26c759277f4..181846760e2 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_06_control_blocks.c @@ -235,7 +235,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -250,7 +250,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.c index ea7398e3bf4..dfd41dfda9b 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.h index 8f8fb971a53..a174c11e201 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_06_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_07_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_07_control_blocks.c index e2eb21769d7..a34da68fb04 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_07_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_07_control_blocks.c @@ -244,7 +244,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -259,7 +259,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.c index aafa7c3dedc..19a9afa213c 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.h index 8f8fb971a53..a174c11e201 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_07_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_08_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_08_control_blocks.c index dc919a61bbc..86dbd5dadea 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_08_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_08_control_blocks.c @@ -244,7 +244,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -259,7 +259,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.c index dcb5a694879..dd5a983893e 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.h index 8f8fb971a53..a174c11e201 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_08_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -63,3 +63,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_09_control_blocks.c b/testdata/p4tc_samples_outputs/tc_may_override_example_09_control_blocks.c index bd4cbe8cc8a..5eb0bbd5fd8 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_09_control_blocks.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_09_control_blocks.c @@ -235,7 +235,7 @@ if (/* hdr->ipv4.isValid() */ return TC_ACT_SHOT; } - hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (htonll(getPrimitive64(hdr->ethernet.dstAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; @@ -250,7 +250,7 @@ if (/* hdr->ipv4.isValid() */ write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (htonll(getPrimitive64(hdr->ethernet.srcAddr, 48) << 16))); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.c b/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.c index 6ee7f4bae87..b9f0b7e9ab4 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.c +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.c @@ -85,10 +85,10 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h goto reject; } - hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.dstAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; - hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + storePrimitive64((u8 *)&hdr->ethernet.srcAddr, 48, (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48))); ebpf_packetOffsetInBits += 48; hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.h b/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.h index 74b1b65a628..1f7bb8949e8 100644 --- a/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.h +++ b/testdata/p4tc_samples_outputs/tc_may_override_example_09_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -62,3 +62,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/tc_type_annotation_example_parser.h b/testdata/p4tc_samples_outputs/tc_type_annotation_example_parser.h index 4206db4108f..677c8612187 100644 --- a/testdata/p4tc_samples_outputs/tc_type_annotation_example_parser.h +++ b/testdata/p4tc_samples_outputs/tc_type_annotation_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -61,3 +61,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} + diff --git a/testdata/p4tc_samples_outputs/test_ipv6_example_control_blocks.c b/testdata/p4tc_samples_outputs/test_ipv6_example_control_blocks.c index 561e55eeb6f..ea5beae16cf 100644 --- a/testdata/p4tc_samples_outputs/test_ipv6_example_control_blocks.c +++ b/testdata/p4tc_samples_outputs/test_ipv6_example_control_blocks.c @@ -177,7 +177,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr, write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0 + 1, 4, 4, (ebpf_byte)); ebpf_packetOffsetInBits += 8; - hdr->ipv6.flowLabel = htonl(hdr->ipv6.flowLabel << 12); + storePrimitive32((u8 *)&hdr->ipv6.flowLabel, 20, (htonl(getPrimitive32(hdr->ipv6.flowLabel, 20) << 12))); ebpf_byte = ((char*)(&hdr->ipv6.flowLabel))[0]; write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 0, (ebpf_byte >> 4)); write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0 + 1, 4, 4, (ebpf_byte)); diff --git a/testdata/p4tc_samples_outputs/test_ipv6_example_parser.c b/testdata/p4tc_samples_outputs/test_ipv6_example_parser.c index 86f16611576..dac5b145a1a 100644 --- a/testdata/p4tc_samples_outputs/test_ipv6_example_parser.c +++ b/testdata/p4tc_samples_outputs/test_ipv6_example_parser.c @@ -41,7 +41,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h hdr->ipv6.trafficClass = (u8)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 8)); ebpf_packetOffsetInBits += 8; - hdr->ipv6.flowLabel = (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits)) >> 8) & EBPF_MASK(u32, 20)); + storePrimitive32((u8 *)&hdr->ipv6.flowLabel, 20, (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits)) >> 8) & EBPF_MASK(u32, 20))); ebpf_packetOffsetInBits += 20; hdr->ipv6.payloadLength = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); diff --git a/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h b/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h index 8d20a6e6c77..692356835b4 100644 --- a/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h +++ b/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h @@ -12,8 +12,8 @@ struct ethernet_t { - u64 dstAddr; /* EthernetAddress */ - u64 srcAddr; /* EthernetAddress */ + u8 dstAddr[6]; /* EthernetAddress */ + u8 srcAddr[6]; /* EthernetAddress */ u16 etherType; /* bit<16> */ u8 ebpf_valid; }; @@ -35,7 +35,7 @@ struct ipv4_t { struct ipv6_t { u8 version; /* bit<4> */ u8 trafficClass; /* bit<8> */ - u32 flowLabel; /* bit<20> */ + u8 flowLabel[3]; /* bit<20> */ u16 payloadLength; /* bit<16> */ u8 nextHeader; /* bit<8> */ u8 hopLimit; /* bit<8> */ @@ -72,3 +72,48 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) REGISTER_END() +u32 getPrimitive32(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + return ((((u32)a[2]) <<16) | (((u32)a[1]) << 8) | a[0]); +} +u64 getPrimitive64(u8 *a, int size) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + if(size <= 40) { + return ((((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + if(size <= 48) { + return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } else { + return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]); + } + } +} +void storePrimitive32(u8 *a, u32 value, int size) { + if(size <=16 || size >=24) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); +} +void storePrimitive64(u8 *a, int size, u64 value) { + if(size <=32 || size >=56) { + error("Invalid size."); + }; + a[0] = (u8)(value); + a[1] = (u8)(value >> 8); + a[2] = (u8)(value >> 16); + a[3] = (u8)(value >> 24); + a[4] = (u8)(value >> 32); + if (size <= 48) { + a[5] = (u8)(value >> 40); + } + if (size > 48 && size <= 56){ + a[6] = (u8)(value >> 48); + } +} +