From e97ec29b8cb8e5fe8948f918116a5536e61e4b89 Mon Sep 17 00:00:00 2001 From: Y Date: Tue, 2 Jul 2024 06:33:42 +0530 Subject: [PATCH] Implementation of InternetChecksum in P4TC --- backends/tc/ebpfCodeGen.cpp | 39 ++ backends/tc/ebpfCodeGen.h | 6 +- backends/tc/runtime/pna.h | 18 +- backends/tc/tcExterns.cpp | 255 ++++++++++ backends/tc/tcExterns.h | 60 +++ testdata/p4tc_samples/internetchecksum_01.p4 | 210 ++++++++ .../add_entry_1_example_parser.h | 8 - .../add_entry_3_example_parser.h | 8 - .../add_entry_example_parser.h | 8 - .../p4tc_samples_outputs/calculator_parser.h | 8 - .../p4tc_samples_outputs/checksum_parser.c | 34 +- .../p4tc_samples_outputs/checksum_parser.h | 8 - .../const_entries_range_mask_parser.h | 8 - .../default_action_example_01_parser.h | 8 - .../default_action_example_parser.h | 8 - .../default_action_with_param_01_parser.h | 8 - .../default_action_with_param_parser.h | 8 - .../default_hit_const_example_parser.h | 8 - .../direct_counter_example_parser.h | 8 - .../drop_packet_example_parser.h | 8 - .../global_action_example_01_parser.h | 8 - .../global_action_example_02_parser.h | 8 - testdata/p4tc_samples_outputs/hash1_parser.h | 8 - .../indirect_counter_01_example_parser.h | 8 - .../internetchecksum_01.json | 85 ++++ .../internetchecksum_01.p4-stderr | 0 .../internetchecksum_01.template | 30 ++ .../internetchecksum_01_control_blocks.c | 478 ++++++++++++++++++ .../internetchecksum_01_parser.c | 190 +++++++ .../internetchecksum_01_parser.h | 179 +++++++ testdata/p4tc_samples_outputs/ipip_parser.h | 8 - .../p4tc_samples_outputs/matchtype_parser.h | 8 - .../mix_matchtype_example_parser.h | 8 - .../multiple_tables_example_01_parser.h | 8 - .../multiple_tables_example_02_parser.h | 8 - .../name_annotation_example_parser.h | 8 - .../no_table_example_parser.h | 8 - .../noaction_example_01_parser.h | 8 - .../noaction_example_02_parser.h | 8 - .../nummask_annotation_example_parser.h | 8 - .../send_to_port_example_parser.h | 8 - .../set_entry_timer_example_parser.h | 8 - .../simple_exact_example_parser.h | 8 - .../simple_extern_example_parser.h | 8 - .../simple_lpm_example_parser.h | 8 - .../simple_ternary_example_parser.h | 8 - .../size_param_example_parser.h | 8 - .../tc_may_override_example_01_parser.h | 8 - .../tc_may_override_example_02_parser.h | 8 - .../tc_may_override_example_03_parser.h | 8 - .../tc_may_override_example_04_parser.h | 8 - .../tc_may_override_example_05_parser.h | 8 - .../tc_may_override_example_06_parser.h | 8 - .../tc_may_override_example_07_parser.h | 8 - .../tc_may_override_example_08_parser.h | 8 - .../tc_may_override_example_09_parser.h | 8 - .../tc_type_annotation_example_parser.h | 8 - .../test_ipv6_example_parser.h | 8 - 58 files changed, 1563 insertions(+), 381 deletions(-) create mode 100644 testdata/p4tc_samples/internetchecksum_01.p4 create mode 100644 testdata/p4tc_samples_outputs/internetchecksum_01.json create mode 100644 testdata/p4tc_samples_outputs/internetchecksum_01.p4-stderr create mode 100755 testdata/p4tc_samples_outputs/internetchecksum_01.template create mode 100644 testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c create mode 100644 testdata/p4tc_samples_outputs/internetchecksum_01_parser.c create mode 100644 testdata/p4tc_samples_outputs/internetchecksum_01_parser.h diff --git a/backends/tc/ebpfCodeGen.cpp b/backends/tc/ebpfCodeGen.cpp index 3bb5a0c4333..2ac207bb6ff 100644 --- a/backends/tc/ebpfCodeGen.cpp +++ b/backends/tc/ebpfCodeGen.cpp @@ -588,6 +588,20 @@ void EBPFPnaParser::emitRejectState(EBPF::CodeBuilder *builder) { builder->endOfStatement(true); } +void EBPFPnaParser::emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) { + if (auto di = decl->to()) { + cstring name = di->name.name; + if (EBPFObject::getTypeName(di) == "InternetChecksum") { + auto instance = new EBPFInternetChecksumPNA(program, di, name); + checksums.emplace(name, instance); + instance->emitVariables(builder); + return; + } + } + + EBPFParser::emitDeclaration(builder, decl); +} + // This code is similar to compileExtractField function in PsaStateTranslationVisitor. // Handled TC "macaddr" annotation. void PnaStateTranslationVisitor::compileExtractField(const IR::Expression *expr, @@ -1223,6 +1237,21 @@ void IngressDeparserPNA::emit(EBPF::CodeBuilder *builder) { builder->newline(); } +void IngressDeparserPNA::emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) { + if (auto di = decl->to()) { + cstring name = di->name.name; + + if (EBPF::EBPFObject::getTypeName(di) == "InternetChecksum") { + auto instance = new EBPFInternetChecksumPNA(program, di, name); + checksums.emplace(name, instance); + instance->emitVariables(builder); + return; + } + } + + EBPFDeparser::emitDeclaration(builder, decl); +} + // =====================ConvertToEbpfPNA============================= const PNAEbpfGenerator *ConvertToEbpfPNA::build(const IR::ToplevelBlock *tlb) { /* @@ -2277,6 +2306,16 @@ void DeparserHdrEmitTranslatorPNA::emitField(EBPF::CodeBuilder *builder, cstring builder->newline(); } +EBPF::EBPFHashAlgorithmPSA *EBPFHashAlgorithmTypeFactoryPNA::create( + int type, const EBPF::EBPFProgram *program, cstring name) { + if (type == EBPF::EBPFHashAlgorithmPSA::HashAlgorithm::ONES_COMPLEMENT16 || + type == EBPF::EBPFHashAlgorithmPSA::HashAlgorithm::TARGET_DEFAULT) { + return new InternetChecksumAlgorithmPNA(program, name); + } + + return nullptr; +} + void CRCChecksumAlgorithmPNA::emitUpdateMethod(EBPF::CodeBuilder *builder, int crcWidth) { // Note that this update method is optimized for our CRC16 and CRC32, custom // version may require other method of update. When data_size <= 64 bits, diff --git a/backends/tc/ebpfCodeGen.h b/backends/tc/ebpfCodeGen.h index a9392f04977..c11256184b1 100644 --- a/backends/tc/ebpfCodeGen.h +++ b/backends/tc/ebpfCodeGen.h @@ -138,6 +138,7 @@ class EBPFPnaParser : public EBPF::EBPFPsaParser { const P4::TypeMap *typeMap); void emit(EBPF::CodeBuilder *builder) override; void emitRejectState(EBPF::CodeBuilder *) override; + void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl); DECLARE_TYPEINFO(EBPFPnaParser, EBPF::EBPFPsaParser); }; @@ -188,6 +189,7 @@ class IngressDeparserPNA : public EBPF::EBPFDeparserPSA { bool build() override; void emit(EBPF::CodeBuilder *builder) override; void emitPreDeparser(EBPF::CodeBuilder *builder) override; + void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl); DECLARE_TYPEINFO(IngressDeparserPNA, EBPF::EBPFDeparserPSA); }; @@ -441,11 +443,13 @@ class EBPFHashAlgorithmTypeFactoryPNA : public EBPF::EBPFHashAlgorithmTypeFactor static EBPFHashAlgorithmTypeFactoryPNA factory; return &factory; } + void emitGlobals(EBPF::CodeBuilder *builder) { CRC16ChecksumAlgorithmPNA::emitGlobals(builder); CRC32ChecksumAlgorithmPNA::emitGlobals(builder); - EBPF::InternetChecksumAlgorithm::emitGlobals(builder); } + + EBPF::EBPFHashAlgorithmPSA *create(int type, const EBPF::EBPFProgram *program, cstring name); }; } // namespace TC diff --git a/backends/tc/runtime/pna.h b/backends/tc/runtime/pna.h index c2d7d6f91f9..6eaff839d07 100644 --- a/backends/tc/runtime/pna.h +++ b/backends/tc/runtime/pna.h @@ -278,32 +278,40 @@ bpf_p4tc_ext_csum_crc16_clear(struct p4tc_ext_csum_params *params) __ksym; /* Basic checksums are not implemented in DPDK */ extern u32 bpf_p4tc_ext_csum_crc32_add(struct p4tc_ext_csum_params *params, + const u32 params__sz, const void *data, const u32 data__sz) __ksym; extern u32 -bpf_p4tc_ext_csum_crc32_get(struct p4tc_ext_csum_params *params) __ksym; +bpf_p4tc_ext_csum_crc32_get(struct p4tc_ext_csum_params *params, + const u32 params__sz) __ksym; extern void -bpf_p4tc_ext_csum_crc32_clear(struct p4tc_ext_csum_params *params) __ksym; +bpf_p4tc_ext_csum_crc32_clear(struct p4tc_ext_csum_params *params, + const u32 params__sz) __ksym; extern u16 -bpf_p4tc_ext_csum_16bit_complement_get(struct p4tc_ext_csum_params *params) __ksym; +bpf_p4tc_ext_csum_16bit_complement_get(struct p4tc_ext_csum_params *params, + const u32 params__sz) __ksym; /* Equivalent to PNA 16bit complement checksum (incremental checksum) */ extern __wsum bpf_p4tc_ext_csum_16bit_complement_add(struct p4tc_ext_csum_params *params, + const u32 params__sz, const void *data, int len) __ksym; extern int bpf_p4tc_ext_csum_16bit_complement_sub(struct p4tc_ext_csum_params *params, + const u32 params__sz, const void *data, const u32 data__sz) __ksym; extern void -bpf_p4tc_ext_csum_16bit_complement_clear(struct p4tc_ext_csum_params *params) __ksym; +bpf_p4tc_ext_csum_16bit_complement_clear(struct p4tc_ext_csum_params *params, + const u32 params__sz) __ksym; extern void bpf_p4tc_ext_csum_16bit_complement_set_state(struct p4tc_ext_csum_params *params, - u16 csum) __ksym; + const u32 params__sz, + u16 csum) __ksym; /* Equivalent to PNA crc16 hash */ extern u16 diff --git a/backends/tc/tcExterns.cpp b/backends/tc/tcExterns.cpp index 08dbb369160..53d16feaca8 100644 --- a/backends/tc/tcExterns.cpp +++ b/backends/tc/tcExterns.cpp @@ -179,4 +179,259 @@ void EBPFCounterPNA::emitCount(EBPF::CodeBuilder *builder, const P4::ExternMetho } } +void EBPFChecksumPNA::init(const EBPF::EBPFProgram *program, cstring name, int type) { + engine = EBPFHashAlgorithmTypeFactoryPNA::instance()->create(type, program, name); + + if (engine == nullptr) { + if (declaration->arguments->empty()) + ::error(ErrorType::ERR_UNSUPPORTED, "InternetChecksum not yet implemented"); + else + ::error(ErrorType::ERR_UNSUPPORTED, "Hash algorithm not yet implemented: %1%", + declaration->arguments->at(0)); + } +} + +void EBPFInternetChecksumPNA::processMethod(EBPF::CodeBuilder *builder, cstring method, + const IR::MethodCallExpression *expr, + Visitor *visitor) { + engine->setVisitor(visitor); + if (method == "add") { + engine->emitAddData(builder, 0, expr); + } else if (method == "subtract") { + engine->emitSubtractData(builder, 0, expr); + } else if (method == "get_state") { + engine->emitGetInternalState(builder); + } else if (method == "set_state") { + engine->emitSetInternalState(builder, expr); + } else if (method == "clear") { + engine->emitClear(builder); + } else if (method == "get") { + engine->emitGet(builder); + } else { + ::error(ErrorType::ERR_UNEXPECTED, "Unexpected method call %1%", expr); + } +} + +void InternetChecksumAlgorithmPNA::emitVariables(EBPF::CodeBuilder *builder, + const IR::Declaration_Instance *decl) { + (void)decl; + stateVar = program->refMap->newName(baseName + "_state"); + csumVar = program->refMap->newName(baseName + "_csum"); + builder->emitIndent(); + builder->appendFormat("u16 %s = 0", stateVar.c_str()); + builder->endOfStatement(true); + builder->appendFormat("struct p4tc_ext_csum_params %s = {};", csumVar.c_str()); + builder->newline(); +} + +void InternetChecksumAlgorithmPNA::emitClear(EBPF::CodeBuilder *builder) { + builder->emitIndent(); + builder->appendFormat("bpf_p4tc_ext_csum_16bit_complement_clear(&%s, sizeof(%s));", + csumVar.c_str(), csumVar.c_str()); + builder->newline(); +} + +void InternetChecksumAlgorithmPNA::emitAddData(EBPF::CodeBuilder *builder, + const ArgumentsList &arguments) { + updateChecksum(builder, arguments, true); +} + +void InternetChecksumAlgorithmPNA::emitGet(EBPF::CodeBuilder *builder) { + builder->appendFormat("(u16) bpf_p4tc_ext_csum_16bit_complement_get(&%s, sizeof(%s));", + csumVar.c_str(), csumVar.c_str()); + builder->newline(); +} + +void InternetChecksumAlgorithmPNA::emitSubtractData(EBPF::CodeBuilder *builder, + const ArgumentsList &arguments) { + updateChecksum(builder, arguments, false); +} + +void InternetChecksumAlgorithmPNA::emitGetInternalState(EBPF::CodeBuilder *builder) { + builder->append(stateVar); +} + +void InternetChecksumAlgorithmPNA::emitSetInternalState(EBPF::CodeBuilder *builder, + const IR::MethodCallExpression *expr) { + if (expr->arguments->size() != 1) { + ::error(ErrorType::ERR_UNEXPECTED, "Expected exactly 1 argument %1%", expr); + return; + } + builder->emitIndent(); + builder->appendFormat("%s = ", stateVar.c_str()); + visitor->visit(expr->arguments->at(0)->expression); + builder->endOfStatement(true); + builder->emitIndent(); + builder->appendFormat("bpf_p4tc_ext_csum_16bit_complement_set_state(&%s, sizeof(%s), ", + csumVar.c_str(), csumVar.c_str()); + visitor->visit(expr->arguments->at(0)->expression); + builder->appendLine(");"); +} + +void InternetChecksumAlgorithmPNA::updateChecksum(EBPF::CodeBuilder *builder, + const ArgumentsList &arguments, bool addData) { + cstring tmpVar = program->refMap->newName(baseName + "_tmp"); + + builder->emitIndent(); + builder->blockStart(); + + builder->emitIndent(); + builder->appendFormat("u16 %s = 0", tmpVar.c_str()); + builder->endOfStatement(true); + + int remainingBits = 16, bitsToRead; + for (auto field : arguments) { + auto fieldType = field->type->to(); + if (fieldType == nullptr) { + ::error(ErrorType::ERR_UNSUPPORTED, "Unsupported field type: %1%", field->type); + return; + } + const int width = fieldType->width_bits(); + bitsToRead = width; + + cstring field_temp = "_temp"_cs; + cstring fieldByteOrder = "HOST"_cs; + auto tcTarget = dynamic_cast(builder->target); + fieldByteOrder = tcTarget->getByteOrder(program->typeMap, NULL, field); + if (fieldByteOrder == "NETWORK"_cs) { + const char *strToken = field->toString().findlast('.'); + if (strToken != nullptr) { + cstring extract(strToken + 1); + field_temp = program->refMap->newName(extract + "_temp"); + } + } + if (width > 64) { + if (remainingBits != 16) { + ::error(ErrorType::ERR_UNSUPPORTED, + "%1%: field wider than 64 bits must be aligned to 16 bits in input data", + field); + continue; + } + if (width % 16 != 0) { + ::error(ErrorType::ERR_UNSUPPORTED, + "%1%: field wider than 64 bits must have size in bits multiply of 16 bits", + field); + continue; + } + + // Let's convert internal array into an array of u16 and calc csum for such entries. + // Byte order conversion is required, because csum is calculated in host byte order + // but data is preserved in network byte order. + const unsigned arrayEntries = width / 16; + for (unsigned i = 0; i < arrayEntries; ++i) { + builder->emitIndent(); + builder->appendFormat("%s = htons(((u16 *)(", tmpVar.c_str()); + visitor->visit(field); + builder->appendFormat("))[%u])", i); + builder->endOfStatement(true); + + // update checksum + builder->target->emitTraceMessage(builder, "InternetChecksum: word=0x%llx", 1, + tmpVar.c_str()); + builder->emitIndent(); + if (addData) { + builder->appendFormat( + "bpf_p4tc_ext_csum_16bit_complement_add(&%s, sizeof(%s), " + "&%s, sizeof(%s))", + csumVar.c_str(), csumVar.c_str(), tmpVar.c_str(), tmpVar.c_str()); + } else { + builder->appendFormat( + "bpf_p4tc_ext_csum_16bit_complement_sub(&%s, sizeof(%s), " + "&%s, sizeof(%s))", + csumVar.c_str(), csumVar.c_str(), tmpVar.c_str(), tmpVar.c_str()); + } + builder->endOfStatement(true); + } + } else { // fields smaller or equal than 64 bits + while (bitsToRead > 0) { + if (fieldByteOrder == "NETWORK"_cs && bitsToRead == width) { + auto etype = EBPF::EBPFTypeFactory::instance->create(field->type); + builder->emitIndent(); + etype->declare(builder, field_temp, false); + builder->appendFormat(" = %s(", + getConvertByteOrderFunction(width, fieldByteOrder)); + visitor->visit(field); + builder->appendLine(");"); + } + if (remainingBits == 16) { + builder->emitIndent(); + builder->appendFormat("%s = ", tmpVar.c_str()); + } else { + builder->append(" | "); + } + + // TODO: add masks for fields, however they should not exceed declared width. + if (bitsToRead < remainingBits) { + remainingBits -= bitsToRead; + builder->append("("); + if (fieldByteOrder == "NETWORK"_cs) { + builder->appendFormat("%s", field_temp); + } else { + visitor->visit(field); + } + builder->appendFormat(" << %d)", remainingBits); + bitsToRead = 0; + } else if (bitsToRead == remainingBits) { + remainingBits = 0; + if (fieldByteOrder == "NETWORK"_cs) { + builder->appendFormat("%s", field_temp); + } else { + visitor->visit(field); + } + bitsToRead = 0; + } else if (bitsToRead > remainingBits) { + bitsToRead -= remainingBits; + remainingBits = 0; + builder->append("("); + if (fieldByteOrder == "NETWORK"_cs) { + builder->appendFormat("%s", field_temp); + } else { + visitor->visit(field); + } + builder->appendFormat(" >> %d)", bitsToRead); + } + + if (remainingBits == 0) { + remainingBits = 16; + builder->endOfStatement(true); + + // update checksum + builder->target->emitTraceMessage(builder, "InternetChecksum: word=0x%llx", 1, + tmpVar.c_str()); + builder->emitIndent(); + if (addData) { + builder->appendFormat( + "bpf_p4tc_ext_csum_16bit_complement_add(&%s, " + "sizeof(%s), &%s, sizeof(%s))", + csumVar.c_str(), csumVar.c_str(), tmpVar.c_str(), tmpVar.c_str()); + } else { + builder->appendFormat( + "bpf_p4tc_ext_csum_16bit_complement_sub(&%s, " + "sizeof(%s), &%s, sizeof(%s))", + csumVar.c_str(), csumVar.c_str(), tmpVar.c_str(), tmpVar.c_str()); + } + builder->endOfStatement(true); + } + } + } + } + + builder->target->emitTraceMessage(builder, "InternetChecksum: new state=0x%llx", 1, + stateVar.c_str()); + builder->blockEnd(true); +} + +cstring InternetChecksumAlgorithmPNA::getConvertByteOrderFunction(unsigned widthToEmit, + cstring byte_order) { + cstring emit; + if (widthToEmit <= 16) { + emit = byte_order == "HOST" ? "bpf_ntohs"_cs : "bpf_htons"_cs; + } else if (widthToEmit <= 32) { + emit = byte_order == "HOST" ? "bpf_ntohl"_cs : "bpf_htonl"_cs; + } else if (widthToEmit <= 64) { + emit = byte_order == "HOST" ? "ntohll"_cs : "bpf_cpu_to_be64"_cs; + } + return emit; +} + } // namespace TC diff --git a/backends/tc/tcExterns.h b/backends/tc/tcExterns.h index 6910b42e07f..a70388215f5 100644 --- a/backends/tc/tcExterns.h +++ b/backends/tc/tcExterns.h @@ -117,6 +117,66 @@ class EBPFTablePNADirectCounterPropertyVisitor : public EBPF::EBPFTablePsaProper } }; +class InternetChecksumAlgorithmPNA : public EBPF::EBPFHashAlgorithmPSA { + protected: + cstring stateVar; + cstring csumVar; + + void updateChecksum(EBPF::CodeBuilder *builder, const ArgumentsList &arguments, bool addData); + + public: + InternetChecksumAlgorithmPNA(const EBPF::EBPFProgram *program, cstring name) + : EBPF::EBPFHashAlgorithmPSA(program, name) {} + + void emitVariables(EBPF::CodeBuilder *builder, const IR::Declaration_Instance *decl) override; + + void emitClear(EBPF::CodeBuilder *builder) override; + void emitAddData(EBPF::CodeBuilder *builder, const ArgumentsList &arguments) override; + void emitGet(EBPF::CodeBuilder *builder) override; + + void emitSubtractData(EBPF::CodeBuilder *builder, const ArgumentsList &arguments) override; + + void emitGetInternalState(EBPF::CodeBuilder *builder) override; + void emitSetInternalState(EBPF::CodeBuilder *builder, + const IR::MethodCallExpression *expr) override; + cstring getConvertByteOrderFunction(unsigned widthToEmit, cstring byte_order); +}; + +class EBPFChecksumPNA : public EBPF::EBPFChecksumPSA { + protected: + void init(const EBPF::EBPFProgram *program, cstring name, int type); + + public: + EBPFChecksumPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block, + cstring name) + : EBPF::EBPFChecksumPSA(program, block, name) { + auto di = block->to(); + if (di->arguments->size() != 1) { + ::error(ErrorType::ERR_UNEXPECTED, "Expected exactly 1 argument %1%", block); + return; + } + int type = di->arguments->at(0)->expression->checkedTo()->asInt(); + init(program, name, type); + } + + EBPFChecksumPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block, + cstring name, int type) + : EBPF::EBPFChecksumPSA(program, block, name, type) { + init(program, name, type); + } +}; + +class EBPFInternetChecksumPNA : public EBPFChecksumPNA { + public: + EBPFInternetChecksumPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block, + cstring name) + : EBPFChecksumPNA(program, block, name, + EBPF::EBPFHashAlgorithmPSA::HashAlgorithm::ONES_COMPLEMENT16) {} + + void processMethod(EBPF::CodeBuilder *builder, cstring method, + const IR::MethodCallExpression *expr, Visitor *visitor) override; +}; + } // namespace TC #endif /* BACKENDS_TC_TCEXTERNS_H_ */ diff --git a/testdata/p4tc_samples/internetchecksum_01.p4 b/testdata/p4tc_samples/internetchecksum_01.p4 new file mode 100644 index 00000000000..907dc5a1232 --- /dev/null +++ b/testdata/p4tc_samples/internetchecksum_01.p4 @@ -0,0 +1,210 @@ +/* -*- P4_16 -*- */ + +#include +#include + +#define PORT_TABLE_SIZE 262144 + +/* + * Standard ethernet header + */ +header ethernet_t { + @tc_type ("macaddr") bit<48> dstAddr; + @tc_type ("macaddr") bit<48> srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + @tc_type ("ipv4") bit<32> srcAddr; + @tc_type ("ipv4") bit<32> dstAddr; +} + +struct my_ingress_headers_t { + ethernet_t ethernet; + ipv4_t outer; + ipv4_t inner; +} + +#define ETHERTYPE_IPV4 0x0800 +#define IPPROTO_IPV4 0x4 + +/****** G L O B A L I N G R E S S M E T A D A T A *********/ + +struct my_ingress_metadata_t { + bit<32> src; + bit<32> dst; + bool push; +} + +struct empty_metadata_t { +} + +error { + BadIPv4HeaderChecksum +} + +void ip_ttl_dec(InternetChecksum chk, inout ipv4_t ip) +{ + chk.clear(); + + chk.set_state(~ip.hdrChecksum); + + chk.subtract({ ip.ttl, ip.protocol }); + + ip.ttl = ip.ttl - 1; + chk.add({ ip.ttl, ip.protocol }); + + ip.hdrChecksum = chk.get(); +} + +void ip_checksum(InternetChecksum chk, inout ipv4_t ip) +{ + chk.clear(); + chk.add({ + /* 16-bit word 0 */ ip.version, ip.ihl, ip.diffserv, + /* 16-bit word 1 */ ip.totalLen, + /* 16-bit word 2 */ ip.identification, + /* 16-bit word 3 */ ip.flags, ip.fragOffset, + /* 16-bit word 4 */ ip.ttl, ip.protocol, + /* 16-bit word 5 skip ip.hdrChecksum, */ + /* 16-bit words 6-7 */ ip.srcAddr, + /* 16-bit words 8-9 */ ip.dstAddr + }); + ip.hdrChecksum = chk.get(); +} + +void ipip_internet_checksum_push(inout my_ingress_headers_t hdr, in my_ingress_metadata_t meta) +{ + hdr.inner = hdr.outer; + hdr.outer.srcAddr = meta.src; + hdr.outer.dstAddr = meta.dst; + hdr.outer.ttl = 64; + hdr.outer.protocol = 4; /* IPIP */ + /* Assume MTU can accomodate +20 bytes */ + hdr.outer.totalLen = hdr.outer.totalLen + 20; + hdr.outer.hdrChecksum = 0; +} + + +/*********************** P A R S E R **************************/ + +parser Ingress_Parser( + packet_in pkt, + out my_ingress_headers_t hdr, + inout my_ingress_metadata_t meta, + in pna_main_parser_input_metadata_t istd) +{ + state start { + transition parse_ethernet; + } + + state parse_ethernet { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + ETHERTYPE_IPV4: parse_ipv4; + default: reject; + } + } + + state parse_ipv4 { + pkt.extract(hdr.outer); + transition select(hdr.outer.protocol) { + IPPROTO_IPV4: parse_ipv4_inner; + default: accept; + } + } + + state parse_ipv4_inner { + pkt.extract(hdr.inner); + transition accept; + } +} + +/***************** M A T C H - A C T I O N *********************/ + +control ingress( + inout my_ingress_headers_t hdr, + inout my_ingress_metadata_t meta, + in pna_main_input_metadata_t istd, + inout pna_main_output_metadata_t ostd +) +{ + action set_ipip_internet_checksum(@tc_type("ipv4") bit<32> src, @tc_type("ipv4") bit<32> dst, @tc_type("dev") PortId_t port) { + meta.src = src; + meta.dst = dst; + meta.push = true; + send_to_port(port); + } + + action set_nh(@tc_type("macaddr") bit<48> dmac, @tc_type("dev") PortId_t port) { + hdr.ethernet.dstAddr = dmac; + send_to_port(port); + } + + action drop() { + drop_packet(); + } + + table fwd_table { + key = { + istd.input_port : exact @tc_type("dev") @name("port"); + } + actions = { + set_ipip_internet_checksum; + set_nh; + drop; + } + default_action = drop; + } + + apply { + if (hdr.outer.isValid()) { /* applies to both ipip_internet_checksum and plain ip */ + fwd_table.apply(); /* lookup based on incoming netdev */ + if (hdr.inner.isValid()) { /* incoming packet ipip_internet_checksum */ + /* Pop the ipip_internet_checksum header by invalidating outer header */ + hdr.outer.setInvalid(); + } + } + } +} + +/********************* D E P A R S E R ************************/ + +control Ingress_Deparser( + packet_out pkt, + inout my_ingress_headers_t hdr, + in my_ingress_metadata_t meta, + in pna_main_output_metadata_t ostd) +{ + InternetChecksum() chk; + + apply { + pkt.emit(hdr.ethernet); + if (meta.push && hdr.outer.isValid()) { + /* Push the ipip_internet_checksum header */ + ipip_internet_checksum_push(hdr, meta); + ip_checksum(chk, hdr.outer); + ip_ttl_dec(chk, hdr.inner); + } + pkt.emit(hdr.outer); + pkt.emit(hdr.inner); + } +} + +/************ F I N A L P A C K A G E ******************************/ + +PNA_NIC( + Ingress_Parser(), + ingress(), + Ingress_Deparser() +) main; 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 cacbbf22572..eb0351243ee 100644 --- a/testdata/p4tc_samples_outputs/add_entry_1_example_parser.h +++ b/testdata/p4tc_samples_outputs/add_entry_1_example_parser.h @@ -157,11 +157,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 cacbbf22572..eb0351243ee 100644 --- a/testdata/p4tc_samples_outputs/add_entry_3_example_parser.h +++ b/testdata/p4tc_samples_outputs/add_entry_3_example_parser.h @@ -157,11 +157,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/add_entry_example_parser.h b/testdata/p4tc_samples_outputs/add_entry_example_parser.h index ba1ef59dc77..c3b7c46eb9b 100644 --- a/testdata/p4tc_samples_outputs/add_entry_example_parser.h +++ b/testdata/p4tc_samples_outputs/add_entry_example_parser.h @@ -157,11 +157,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/calculator_parser.h b/testdata/p4tc_samples_outputs/calculator_parser.h index 37448997b39..ba89b9929a1 100644 --- a/testdata/p4tc_samples_outputs/calculator_parser.h +++ b/testdata/p4tc_samples_outputs/calculator_parser.h @@ -148,11 +148,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/checksum_parser.c b/testdata/p4tc_samples_outputs/checksum_parser.c index 816255750d4..81ce9bbd2bd 100644 --- a/testdata/p4tc_samples_outputs/checksum_parser.c +++ b/testdata/p4tc_samples_outputs/checksum_parser.c @@ -29,6 +29,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h { u16 tmp_0; u16 ck_0_state = 0; +struct p4tc_ext_csum_params ck_0_csum = {}; goto start; parse_ipv4: { /* extract(hdr->ipv4) */ @@ -79,33 +80,36 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h ; /* ck_0.clear() */ - ck_0_state = 0; + bpf_p4tc_ext_csum_16bit_complement_clear(&ck_0_csum, sizeof(ck_0_csum)); ; /* ck_0.add((struct tuple_0){.f0 = hdr->ipv4.version, .f1 = hdr->ipv4.ihl, .f2 = hdr->ipv4.diffserv, .f3 = hdr->ipv4.totalLen, .f4 = hdr->ipv4.identification, .f5 = hdr->ipv4.flags, .f6 = hdr->ipv4.fragOffset, .f7 = hdr->ipv4.ttl, .f8 = hdr->ipv4.protocol, .f9 = hdr->ipv4.srcAddr, .f10 = hdr->ipv4.dstAddr}) */ { u16 ck_0_tmp = 0; ck_0_tmp = (hdr->ipv4.version << 12) | (hdr->ipv4.ihl << 8) | hdr->ipv4.diffserv; - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); ck_0_tmp = hdr->ipv4.totalLen; - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); ck_0_tmp = hdr->ipv4.identification; - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); ck_0_tmp = (hdr->ipv4.flags << 13) | hdr->ipv4.fragOffset; - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); ck_0_tmp = (hdr->ipv4.ttl << 8) | hdr->ipv4.protocol; - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); - ck_0_tmp = (hdr->ipv4.srcAddr >> 16); - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); - ck_0_tmp = hdr->ipv4.srcAddr; - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); - ck_0_tmp = (hdr->ipv4.dstAddr >> 16); - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); - ck_0_tmp = hdr->ipv4.dstAddr; - ck_0_state = csum16_add(ck_0_state, ck_0_tmp); + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); + u32 srcAddr_temp = bpf_htonl(hdr->ipv4.srcAddr); + ck_0_tmp = (srcAddr_temp >> 16); + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); + ck_0_tmp = srcAddr_temp; + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); + u32 dstAddr_temp = bpf_htonl(hdr->ipv4.dstAddr); + ck_0_tmp = (dstAddr_temp >> 16); + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); + ck_0_tmp = dstAddr_temp; + bpf_p4tc_ext_csum_16bit_complement_add(&ck_0_csum, sizeof(ck_0_csum), &ck_0_tmp, sizeof(ck_0_tmp)); } ; tmp_0 = /* ck_0.get() */ -((u16) (~ck_0_state));/* verify(hdr->ipv4.hdrChecksum == tmp_0, BadIPv4HeaderChecksum) */ +(u16) bpf_p4tc_ext_csum_16bit_complement_get(&ck_0_csum, sizeof(ck_0_csum)); +;/* verify(hdr->ipv4.hdrChecksum == tmp_0, BadIPv4HeaderChecksum) */ if (!(hdr->ipv4.hdrChecksum == tmp_0)) { ebpf_errorCode = BadIPv4HeaderChecksum; goto reject; diff --git a/testdata/p4tc_samples_outputs/checksum_parser.h b/testdata/p4tc_samples_outputs/checksum_parser.h index 13520a65be2..3e5caec29fc 100644 --- a/testdata/p4tc_samples_outputs/checksum_parser.h +++ b/testdata/p4tc_samples_outputs/checksum_parser.h @@ -171,11 +171,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 6cd09d7d7e8..9ec0cd912fe 100644 --- a/testdata/p4tc_samples_outputs/const_entries_range_mask_parser.h +++ b/testdata/p4tc_samples_outputs/const_entries_range_mask_parser.h @@ -139,11 +139,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/default_action_example_01_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/default_action_example_parser.h b/testdata/p4tc_samples_outputs/default_action_example_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/default_action_example_parser.h +++ b/testdata/p4tc_samples_outputs/default_action_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 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 @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/default_action_with_param_parser.h +++ b/testdata/p4tc_samples_outputs/default_action_with_param_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 7f7c95824d3..d0f8789a8f6 100644 --- a/testdata/p4tc_samples_outputs/default_hit_const_example_parser.h +++ b/testdata/p4tc_samples_outputs/default_hit_const_example_parser.h @@ -167,11 +167,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/direct_counter_example_parser.h b/testdata/p4tc_samples_outputs/direct_counter_example_parser.h index a67ccde435a..7c722359cc5 100644 --- a/testdata/p4tc_samples_outputs/direct_counter_example_parser.h +++ b/testdata/p4tc_samples_outputs/direct_counter_example_parser.h @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/drop_packet_example_parser.h b/testdata/p4tc_samples_outputs/drop_packet_example_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/drop_packet_example_parser.h +++ b/testdata/p4tc_samples_outputs/drop_packet_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 a67ccde435a..7c722359cc5 100644 --- a/testdata/p4tc_samples_outputs/global_action_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/global_action_example_01_parser.h @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 a67ccde435a..7c722359cc5 100644 --- a/testdata/p4tc_samples_outputs/global_action_example_02_parser.h +++ b/testdata/p4tc_samples_outputs/global_action_example_02_parser.h @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/hash1_parser.h b/testdata/p4tc_samples_outputs/hash1_parser.h index ccbef335c7f..42a9f99a839 100644 --- a/testdata/p4tc_samples_outputs/hash1_parser.h +++ b/testdata/p4tc_samples_outputs/hash1_parser.h @@ -170,11 +170,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 a67ccde435a..7c722359cc5 100644 --- a/testdata/p4tc_samples_outputs/indirect_counter_01_example_parser.h +++ b/testdata/p4tc_samples_outputs/indirect_counter_01_example_parser.h @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01.json b/testdata/p4tc_samples_outputs/internetchecksum_01.json new file mode 100644 index 00000000000..9f426a986aa --- /dev/null +++ b/testdata/p4tc_samples_outputs/internetchecksum_01.json @@ -0,0 +1,85 @@ +{ + "schema_version" : "1.0.0", + "pipeline_name" : "internetchecksum_01", + "externs" : [], + "tables" : [ + { + "name" : "ingress/fwd_table", + "id" : 1, + "tentries" : 1024, + "permissions" : "0x3da4", + "nummask" : 8, + "keysize" : 32, + "keyfields" : [ + { + "id" : 1, + "name" : "port", + "type" : "dev", + "match_type" : "exact", + "bitwidth" : 32 + } + ], + "actions" : [ + { + "id" : 1, + "name" : "ingress/set_ipip_internet_checksum", + "action_scope" : "TableAndDefault", + "annotations" : [], + "params" : [ + { + "id" : 1, + "name" : "src", + "type" : "ipv4", + "bitwidth" : 32 + }, + { + "id" : 2, + "name" : "dst", + "type" : "ipv4", + "bitwidth" : 32 + }, + { + "id" : 3, + "name" : "port", + "type" : "dev", + "bitwidth" : 32 + } + ], + "default_hit_action" : false, + "default_miss_action" : false + }, + { + "id" : 2, + "name" : "ingress/set_nh", + "action_scope" : "TableAndDefault", + "annotations" : [], + "params" : [ + { + "id" : 1, + "name" : "dmac", + "type" : "macaddr", + "bitwidth" : 48 + }, + { + "id" : 2, + "name" : "port", + "type" : "dev", + "bitwidth" : 32 + } + ], + "default_hit_action" : false, + "default_miss_action" : false + }, + { + "id" : 3, + "name" : "ingress/drop", + "action_scope" : "TableAndDefault", + "annotations" : [], + "params" : [], + "default_hit_action" : false, + "default_miss_action" : true + } + ] + } + ] +} \ No newline at end of file diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01.p4-stderr b/testdata/p4tc_samples_outputs/internetchecksum_01.p4-stderr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01.template b/testdata/p4tc_samples_outputs/internetchecksum_01.template new file mode 100755 index 00000000000..3fec551d379 --- /dev/null +++ b/testdata/p4tc_samples_outputs/internetchecksum_01.template @@ -0,0 +1,30 @@ +#!/bin/bash -x + +set -e + +TC="tc" +$TC p4template create pipeline/internetchecksum_01 numtables 1 + +$TC p4template create action/internetchecksum_01/ingress/set_ipip_internet_checksum actid 1 \ + param src type ipv4 \ + param dst type ipv4 \ + param port type dev +$TC p4template update action/internetchecksum_01/ingress/set_ipip_internet_checksum state active + +$TC p4template create action/internetchecksum_01/ingress/set_nh actid 2 \ + param dmac type macaddr \ + param port type dev +$TC p4template update action/internetchecksum_01/ingress/set_nh state active + +$TC p4template create action/internetchecksum_01/ingress/drop actid 3 +$TC p4template update action/internetchecksum_01/ingress/drop state active + +$TC p4template create table/internetchecksum_01/ingress/fwd_table \ + tblid 1 \ + type exact \ + keysz 32 nummasks 8 permissions 0x3da4 tentries 1024 \ + table_acts act name internetchecksum_01/ingress/set_ipip_internet_checksum \ + act name internetchecksum_01/ingress/set_nh \ + act name internetchecksum_01/ingress/drop +$TC p4template update table/internetchecksum_01/ingress/fwd_table default_miss_action action internetchecksum_01/ingress/drop +$TC p4template update pipeline/internetchecksum_01 state ready \ No newline at end of file diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c b/testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c new file mode 100644 index 00000000000..6bb7058f7d6 --- /dev/null +++ b/testdata/p4tc_samples_outputs/internetchecksum_01_control_blocks.c @@ -0,0 +1,478 @@ +#include "internetchecksum_01_parser.h" +struct p4tc_filter_fields p4tc_filter_fields; + +struct internal_metadata { + __u16 pkt_ether_type; +} __attribute__((aligned(4))); + +struct __attribute__((__packed__)) ingress_fwd_table_key { + u32 keysz; + u32 maskid; + u32 field0; /* istd.input_port */ +} __attribute__((aligned(8))); +#define INGRESS_FWD_TABLE_ACT_INGRESS_SET_IPIP_INTERNET_CHECKSUM 1 +#define INGRESS_FWD_TABLE_ACT_INGRESS_SET_NH 2 +#define INGRESS_FWD_TABLE_ACT_INGRESS_DROP 3 +#define INGRESS_FWD_TABLE_ACT_NOACTION 0 +struct __attribute__((__packed__)) ingress_fwd_table_value { + unsigned int action; + u32 hit:1, + is_default_miss_act:1, + is_default_hit_act:1; + union { + struct { + } _NoAction; + struct __attribute__((__packed__)) { + u32 src; + u32 dst; + u32 port; + } ingress_set_ipip_internet_checksum; + struct __attribute__((__packed__)) { + u64 dmac; + u32 port; + } ingress_set_nh; + struct { + } ingress_drop; + } u; +}; + +static __always_inline int process(struct __sk_buff *skb, struct my_ingress_headers_t *hdr, struct pna_global_metadata *compiler_meta__) +{ + struct hdr_md *hdrMd; + + unsigned ebpf_packetOffsetInBits_save = 0; + ParserError_t ebpf_errorCode = NoError; + void* pkt = ((void*)(long)skb->data); + u8* hdr_start = pkt; + void* ebpf_packetEnd = ((void*)(long)skb->data_end); + u32 ebpf_zero = 0; + u32 ebpf_one = 1; + unsigned char ebpf_byte; + u32 pkt_len = skb->len; + + struct my_ingress_metadata_t *meta; + hdrMd = BPF_MAP_LOOKUP_ELEM(hdr_md_cpumap, &ebpf_zero); + if (!hdrMd) + return TC_ACT_SHOT; + unsigned ebpf_packetOffsetInBits = hdrMd->ebpf_packetOffsetInBits; + hdr_start = pkt + BYTES(ebpf_packetOffsetInBits); + hdr = &(hdrMd->cpumap_hdr); + meta = &(hdrMd->cpumap_usermeta); +{ + u8 hit; + { +if (/* hdr->outer.isValid() */ + hdr->outer.ebpf_valid) { +/* fwd_table_0.apply() */ + { + /* construct key */ + struct p4tc_table_entry_act_bpf_params__local params = { + .pipeid = p4tc_filter_fields.pipeid, + .tblid = 1 + }; + struct ingress_fwd_table_key key; + __builtin_memset(&key, 0, sizeof(key)); + key.keysz = 32; + key.field0 = skb->ifindex; + struct p4tc_table_entry_act_bpf *act_bpf; + /* value */ + struct ingress_fwd_table_value *value = NULL; + /* perform lookup */ + act_bpf = bpf_p4tc_tbl_read(skb, ¶ms, sizeof(params), &key, sizeof(key)); + value = (struct ingress_fwd_table_value *)act_bpf; + if (value == NULL) { + /* miss; find default action */ + hit = 0; + } else { + hit = value->hit; + } + if (value != NULL) { + /* run action */ + switch (value->action) { + case INGRESS_FWD_TABLE_ACT_INGRESS_SET_IPIP_INTERNET_CHECKSUM: + { + meta->src = bpf_ntohl(value->u.ingress_set_ipip_internet_checksum.src); + meta->dst = bpf_ntohl(value->u.ingress_set_ipip_internet_checksum.dst); + meta->push = true; + /* send_to_port(value->u.ingress_set_ipip_internet_checksum.port) */ + compiler_meta__->drop = false; + send_to_port(value->u.ingress_set_ipip_internet_checksum.port); + } + break; + case INGRESS_FWD_TABLE_ACT_INGRESS_SET_NH: + { + hdr->ethernet.dstAddr = value->u.ingress_set_nh.dmac; + /* send_to_port(value->u.ingress_set_nh.port) */ + compiler_meta__->drop = false; + send_to_port(value->u.ingress_set_nh.port); + } + break; + case INGRESS_FWD_TABLE_ACT_INGRESS_DROP: + { +/* drop_packet() */ + drop_packet(); + } + break; + case INGRESS_FWD_TABLE_ACT_NOACTION: + { + } + break; + } + } else { + } + } +; + if (/* hdr->inner.isValid() */ + hdr->inner.ebpf_valid) { +/* hdr->outer.setInvalid() */ + hdr->outer.ebpf_valid = false; } + + } + } + } + { + struct my_ingress_headers_t *hdr_1; + struct my_ingress_metadata_t *meta_1; + struct ipv4_t ip; + __builtin_memset((void *) &ip, 0, sizeof(struct ipv4_t )); + struct ipv4_t ip_2; + __builtin_memset((void *) &ip_2, 0, sizeof(struct ipv4_t )); + u16 chk_state = 0; +struct p4tc_ext_csum_params chk_csum = {}; +{ +; + if (meta->push && /* hdr->outer.isValid() */ + hdr->outer.ebpf_valid) { + hdr_1 = hdr; + meta_1 = meta; + hdr_1->inner = hdr_1->outer; + hdr_1->outer.srcAddr = bpf_htonl(meta_1->src); + hdr_1->outer.dstAddr = bpf_htonl(meta_1->dst); + hdr_1->outer.ttl = 64; + hdr_1->outer.protocol = 4; + hdr_1->outer.totalLen = (hdr_1->outer.totalLen + 20); + hdr_1->outer.hdrChecksum = 0; + hdr = hdr_1; + ip = hdr->outer; + /* chk.clear() */ + bpf_p4tc_ext_csum_16bit_complement_clear(&chk_csum, sizeof(chk_csum)); +; + /* chk.add({ip.version, ip.ihl, ip.diffserv, ip.totalLen, ip.identification, ip.flags, ip.fragOffset, ip.ttl, ip.protocol, ip.srcAddr, ip.dstAddr}) */ + { + u16 chk_tmp = 0; + chk_tmp = (ip.version << 12) | (ip.ihl << 8) | ip.diffserv; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + chk_tmp = ip.totalLen; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + chk_tmp = ip.identification; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + chk_tmp = (ip.flags << 13) | ip.fragOffset; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + chk_tmp = (ip.ttl << 8) | ip.protocol; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + u32 srcAddr_temp = bpf_htonl(ip.srcAddr); + chk_tmp = (srcAddr_temp >> 16); + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + chk_tmp = srcAddr_temp; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + u32 dstAddr_temp = bpf_htonl(ip.dstAddr); + chk_tmp = (dstAddr_temp >> 16); + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + chk_tmp = dstAddr_temp; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp, sizeof(chk_tmp)); + } +; + ip.hdrChecksum = /* chk.get() */ +(u16) bpf_p4tc_ext_csum_16bit_complement_get(&chk_csum, sizeof(chk_csum)); +; + hdr->outer = ip; + ip_2 = hdr->inner; + /* chk.clear() */ + bpf_p4tc_ext_csum_16bit_complement_clear(&chk_csum, sizeof(chk_csum)); +; + /* chk.set_state(~ip_2.hdrChecksum) */ + chk_state = ~ip_2.hdrChecksum; + bpf_p4tc_ext_csum_16bit_complement_set_state(&chk_csum, sizeof(chk_csum), ~ip_2.hdrChecksum); +; + /* chk.subtract({ip_2.ttl, ip_2.protocol}) */ + { + u16 chk_tmp_0 = 0; + chk_tmp_0 = (ip_2.ttl << 8) | ip_2.protocol; + bpf_p4tc_ext_csum_16bit_complement_sub(&chk_csum, sizeof(chk_csum), &chk_tmp_0, sizeof(chk_tmp_0)); + } +; + ip_2.ttl = (ip_2.ttl + 255); + /* chk.add({ip_2.ttl, ip_2.protocol}) */ + { + u16 chk_tmp_1 = 0; + chk_tmp_1 = (ip_2.ttl << 8) | ip_2.protocol; + bpf_p4tc_ext_csum_16bit_complement_add(&chk_csum, sizeof(chk_csum), &chk_tmp_1, sizeof(chk_tmp_1)); + } +; + ip_2.hdrChecksum = /* chk.get() */ +(u16) bpf_p4tc_ext_csum_16bit_complement_get(&chk_csum, sizeof(chk_csum)); +; + hdr->inner = ip_2; + } + ; + ; + } + + if (compiler_meta__->drop) { + return TC_ACT_SHOT; + } + int outHeaderLength = 0; + if (hdr->ethernet.ebpf_valid) { + outHeaderLength += 112; + } +; if (hdr->outer.ebpf_valid) { + outHeaderLength += 160; + } +; if (hdr->inner.ebpf_valid) { + outHeaderLength += 160; + } +; + int outHeaderOffset = BYTES(outHeaderLength) - (hdr_start - (u8*)pkt); + if (outHeaderOffset != 0) { + int returnCode = 0; + returnCode = bpf_skb_adjust_room(skb, outHeaderOffset, 1, 0); + if (returnCode) { + return TC_ACT_SHOT; + } + } + pkt = ((void*)(long)skb->data); + ebpf_packetEnd = ((void*)(long)skb->data_end); + ebpf_packetOffsetInBits = 0; + if (hdr->ethernet.ebpf_valid) { + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 112)) { + return TC_ACT_SHOT; + } + + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[4]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[5]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); + ebpf_packetOffsetInBits += 48; + + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[4]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[5]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); + ebpf_packetOffsetInBits += 48; + + hdr->ethernet.etherType = bpf_htons(hdr->ethernet.etherType); + ebpf_byte = ((char*)(&hdr->ethernet.etherType))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.etherType))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + } +; if (hdr->outer.ebpf_valid) { + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 160)) { + return TC_ACT_SHOT; + } + + ebpf_byte = ((char*)(&hdr->outer.version))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 4, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->outer.ihl))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 0, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->outer.diffserv))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->outer.totalLen = bpf_htons(hdr->outer.totalLen); + ebpf_byte = ((char*)(&hdr->outer.totalLen))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.totalLen))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + hdr->outer.identification = bpf_htons(hdr->outer.identification); + ebpf_byte = ((char*)(&hdr->outer.identification))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.identification))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + ebpf_byte = ((char*)(&hdr->outer.flags))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 3, 5, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 3; + + hdr->outer.fragOffset = bpf_htons(hdr->outer.fragOffset << 3); + ebpf_byte = ((char*)(&hdr->outer.fragOffset))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 5, 0, (ebpf_byte >> 3)); + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0 + 1, 3, 5, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.fragOffset))[1]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 1, 5, 0, (ebpf_byte >> 3)); + ebpf_packetOffsetInBits += 13; + + ebpf_byte = ((char*)(&hdr->outer.ttl))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + ebpf_byte = ((char*)(&hdr->outer.protocol))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->outer.hdrChecksum = bpf_htons(hdr->outer.hdrChecksum); + ebpf_byte = ((char*)(&hdr->outer.hdrChecksum))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.hdrChecksum))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + } +; if (hdr->inner.ebpf_valid) { + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 160)) { + return TC_ACT_SHOT; + } + + ebpf_byte = ((char*)(&hdr->inner.version))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 4, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->inner.ihl))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 0, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->inner.diffserv))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->inner.totalLen = bpf_htons(hdr->inner.totalLen); + ebpf_byte = ((char*)(&hdr->inner.totalLen))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.totalLen))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + hdr->inner.identification = bpf_htons(hdr->inner.identification); + ebpf_byte = ((char*)(&hdr->inner.identification))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.identification))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + ebpf_byte = ((char*)(&hdr->inner.flags))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 3, 5, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 3; + + hdr->inner.fragOffset = bpf_htons(hdr->inner.fragOffset << 3); + ebpf_byte = ((char*)(&hdr->inner.fragOffset))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 5, 0, (ebpf_byte >> 3)); + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0 + 1, 3, 5, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.fragOffset))[1]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 1, 5, 0, (ebpf_byte >> 3)); + ebpf_packetOffsetInBits += 13; + + ebpf_byte = ((char*)(&hdr->inner.ttl))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + ebpf_byte = ((char*)(&hdr->inner.protocol))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->inner.hdrChecksum = bpf_htons(hdr->inner.hdrChecksum); + ebpf_byte = ((char*)(&hdr->inner.hdrChecksum))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.hdrChecksum))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + } +; + } + return -1; +} +SEC("p4tc/main") +int tc_ingress_func(struct __sk_buff *skb) { + struct pna_global_metadata *compiler_meta__ = (struct pna_global_metadata *) skb->cb; + if (compiler_meta__->pass_to_kernel == true) return TC_ACT_OK; + compiler_meta__->drop = false; + if (!compiler_meta__->recirculated) { + compiler_meta__->mark = 153; + struct internal_metadata *md = (struct internal_metadata *)(unsigned long)skb->data_meta; + if ((void *) ((struct internal_metadata *) md + 1) <= (void *)(long)skb->data) { + __u16 *ether_type = (__u16 *) ((void *) (long)skb->data + 12); + if ((void *) ((__u16 *) ether_type + 1) > (void *) (long) skb->data_end) { + return TC_ACT_SHOT; + } + *ether_type = md->pkt_ether_type; + } + } + struct hdr_md *hdrMd; + struct my_ingress_headers_t *hdr; + int ret = -1; + ret = process(skb, (struct my_ingress_headers_t *) hdr, compiler_meta__); + if (ret != -1) { + return ret; + } + if (!compiler_meta__->drop && compiler_meta__->egress_port == 0) { + compiler_meta__->pass_to_kernel = true; + return bpf_redirect(skb->ifindex, BPF_F_INGRESS); + } + return bpf_redirect(compiler_meta__->egress_port, 0); +} +char _license[] SEC("license") = "GPL"; diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01_parser.c b/testdata/p4tc_samples_outputs/internetchecksum_01_parser.c new file mode 100644 index 00000000000..cb2a2966253 --- /dev/null +++ b/testdata/p4tc_samples_outputs/internetchecksum_01_parser.c @@ -0,0 +1,190 @@ +#include "internetchecksum_01_parser.h" + +struct p4tc_filter_fields p4tc_filter_fields; + +static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_headers_t *hdr, struct pna_global_metadata *compiler_meta__) +{ + struct hdr_md *hdrMd; + + unsigned ebpf_packetOffsetInBits_save = 0; + ParserError_t ebpf_errorCode = NoError; + void* pkt = ((void*)(long)skb->data); + u8* hdr_start = pkt; + void* ebpf_packetEnd = ((void*)(long)skb->data_end); + u32 ebpf_zero = 0; + u32 ebpf_one = 1; + unsigned char ebpf_byte; + u32 pkt_len = skb->len; + + struct my_ingress_metadata_t *meta; + + hdrMd = BPF_MAP_LOOKUP_ELEM(hdr_md_cpumap, &ebpf_zero); + if (!hdrMd) + return TC_ACT_SHOT; + __builtin_memset(hdrMd, 0, sizeof(struct hdr_md)); + + unsigned ebpf_packetOffsetInBits = 0; + hdr = &(hdrMd->cpumap_hdr); + meta = &(hdrMd->cpumap_usermeta); + { + goto start; + parse_ipv4: { +/* extract(hdr->outer) */ + if ((u8*)ebpf_packetEnd < hdr_start + BYTES(160 + 0)) { + ebpf_errorCode = PacketTooShort; + goto reject; + } + + hdr->outer.version = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->outer.ihl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->outer.diffserv = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->outer.totalLen = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->outer.identification = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->outer.flags = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 5) & EBPF_MASK(u8, 3)); + ebpf_packetOffsetInBits += 3; + + hdr->outer.fragOffset = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u16, 13)); + ebpf_packetOffsetInBits += 13; + + hdr->outer.ttl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->outer.protocol = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->outer.hdrChecksum = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + __builtin_memcpy(&hdr->outer.srcAddr, pkt + BYTES(ebpf_packetOffsetInBits), 4); + ebpf_packetOffsetInBits += 32; + + __builtin_memcpy(&hdr->outer.dstAddr, pkt + BYTES(ebpf_packetOffsetInBits), 4); + ebpf_packetOffsetInBits += 32; + + + hdr->outer.ebpf_valid = 1; + hdr_start += BYTES(160); + +; + u8 select_0; + select_0 = hdr->outer.protocol; + if (select_0 == 0x4)goto parse_ipv4_inner; + if ((select_0 & 0x0) == (0x0 & 0x0))goto accept; + else goto reject; + } + parse_ipv4_inner: { +/* extract(hdr->inner) */ + if ((u8*)ebpf_packetEnd < hdr_start + BYTES(160 + 0)) { + ebpf_errorCode = PacketTooShort; + goto reject; + } + + hdr->inner.version = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->inner.ihl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->inner.diffserv = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->inner.totalLen = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->inner.identification = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->inner.flags = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 5) & EBPF_MASK(u8, 3)); + ebpf_packetOffsetInBits += 3; + + hdr->inner.fragOffset = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u16, 13)); + ebpf_packetOffsetInBits += 13; + + hdr->inner.ttl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->inner.protocol = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->inner.hdrChecksum = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + __builtin_memcpy(&hdr->inner.srcAddr, pkt + BYTES(ebpf_packetOffsetInBits), 4); + ebpf_packetOffsetInBits += 32; + + __builtin_memcpy(&hdr->inner.dstAddr, pkt + BYTES(ebpf_packetOffsetInBits), 4); + ebpf_packetOffsetInBits += 32; + + + hdr->inner.ebpf_valid = 1; + hdr_start += BYTES(160); + +; + goto accept; + } + start: { +/* extract(hdr->ethernet) */ + if ((u8*)ebpf_packetEnd < hdr_start + BYTES(112 + 0)) { + ebpf_errorCode = PacketTooShort; + goto reject; + } + + __builtin_memcpy(&hdr->ethernet.dstAddr, pkt + BYTES(ebpf_packetOffsetInBits), 6); + ebpf_packetOffsetInBits += 48; + + __builtin_memcpy(&hdr->ethernet.srcAddr, pkt + BYTES(ebpf_packetOffsetInBits), 6); + ebpf_packetOffsetInBits += 48; + + hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + + hdr->ethernet.ebpf_valid = 1; + hdr_start += BYTES(112); + +; + u16 select_1; + select_1 = hdr->ethernet.etherType; + if (select_1 == 0x800)goto parse_ipv4; + if ((select_1 & 0x0) == (0x0 & 0x0))goto reject; + else goto reject; + } + + reject: { + if (ebpf_errorCode == 0) { + return TC_ACT_SHOT; + } + compiler_meta__->parser_error = ebpf_errorCode; + goto accept; + } + + } + + accept: + hdrMd->ebpf_packetOffsetInBits = ebpf_packetOffsetInBits; + return -1; +} + +SEC("p4tc/parse") +int tc_parse_func(struct __sk_buff *skb) { + struct pna_global_metadata *compiler_meta__ = (struct pna_global_metadata *) skb->cb; + struct hdr_md *hdrMd; + struct my_ingress_headers_t *hdr; + int ret = -1; + ret = run_parser(skb, (struct my_ingress_headers_t *) hdr, compiler_meta__); + if (ret != -1) { + return ret; + } + return TC_ACT_PIPE; + } +char _license[] SEC("license") = "GPL"; diff --git a/testdata/p4tc_samples_outputs/internetchecksum_01_parser.h b/testdata/p4tc_samples_outputs/internetchecksum_01_parser.h new file mode 100644 index 00000000000..849fc36394e --- /dev/null +++ b/testdata/p4tc_samples_outputs/internetchecksum_01_parser.h @@ -0,0 +1,179 @@ +#include "ebpf_kernel.h" + +#include +#include +#include "pna.h" + +#define EBPF_MASK(t, w) ((((t)(1)) << (w)) - (t)1) +#define BYTES(w) ((w) / 8) +#define write_partial(a, w, s, v) do { *((u8*)a) = ((*((u8*)a)) & ~(EBPF_MASK(u8, w) << s)) | (v << s) ; } while (0) +#define write_byte(base, offset, v) do { *(u8*)((base) + (offset)) = (v); } while (0) +#define bpf_trace_message(fmt, ...) + + +struct ethernet_t { + u64 dstAddr; /* bit<48> */ + u64 srcAddr; /* bit<48> */ + u16 etherType; /* bit<16> */ + u8 ebpf_valid; +}; +struct ipv4_t { + u8 version; /* bit<4> */ + u8 ihl; /* bit<4> */ + u8 diffserv; /* bit<8> */ + u16 totalLen; /* bit<16> */ + u16 identification; /* bit<16> */ + u8 flags; /* bit<3> */ + u16 fragOffset; /* bit<13> */ + u8 ttl; /* bit<8> */ + u8 protocol; /* bit<8> */ + u16 hdrChecksum; /* bit<16> */ + u32 srcAddr; /* bit<32> */ + u32 dstAddr; /* bit<32> */ + u8 ebpf_valid; +}; +struct my_ingress_headers_t { + struct ethernet_t ethernet; /* ethernet_t */ + struct ipv4_t outer; /* ipv4_t */ + struct ipv4_t inner; /* ipv4_t */ +}; +struct my_ingress_metadata_t { + u32 src; /* bit<32> */ + u32 dst; /* bit<32> */ + u8 push; /* bool */ +}; +struct empty_metadata_t { +}; +struct tuple_0 { + u8 f0; /* bit<4> */ + u8 f1; /* bit<4> */ + u8 f2; /* bit<8> */ + u16 f3; /* bit<16> */ + u16 f4; /* bit<16> */ + u8 f5; /* bit<3> */ + u16 f6; /* bit<13> */ + u8 f7; /* bit<8> */ + u8 f8; /* bit<8> */ + u32 f9; /* bit<32> */ + u32 f10; /* bit<32> */ +}; +struct tuple_1 { + u8 f0; /* bit<8> */ + u8 f1; /* bit<8> */ +}; +static const ParserError_t BadIPv4HeaderChecksum = 7; + +struct hdr_md { + struct my_ingress_headers_t cpumap_hdr; + struct my_ingress_metadata_t cpumap_usermeta; + unsigned ebpf_packetOffsetInBits; + __u8 __hook; +}; + +struct p4tc_filter_fields { + __u32 pipeid; + __u32 handle; + __u32 classid; + __u32 chain; + __u32 blockid; + __be16 proto; + __u16 prio; +}; + +REGISTER_START() +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() + +static __always_inline +void crc16_update(u16 * reg, const u8 * data, u16 data_size, const u16 poly) { + if (data_size <= 8) + data += data_size - 1; + #pragma clang loop unroll(full) + for (u16 i = 0; i < data_size; i++) { + bpf_trace_message("CRC16: data byte: %x\n", *data); + *reg ^= *data; + for (u8 bit = 0; bit < 8; bit++) { + *reg = (*reg) & 1 ? ((*reg) >> 1) ^ poly : (*reg) >> 1; + } + if (data_size <= 8) + data--; + else + data++; + } +} +static __always_inline u16 crc16_finalize(u16 reg) { + return reg; +} +static __always_inline +void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { + u32* current = (u32*) data; + u32 index = 0; + u32 lookup_key = 0; + u32 lookup_value = 0; + u32 lookup_value1 = 0; + u32 lookup_value2 = 0; + u32 lookup_value3 = 0; + u32 lookup_value4 = 0; + u32 lookup_value5 = 0; + u32 lookup_value6 = 0; + u32 lookup_value7 = 0; + u32 lookup_value8 = 0; + u16 tmp = 0; + if (crc32_table != NULL) { + for (u16 i = data_size; i >= 8; i -= 8) { + /* Vars one and two will have swapped byte order if data_size == 8 */ + if (data_size == 8) current = (u32 *)(data + 4); + bpf_trace_message("CRC32: data dword: %x\n", *current); + u32 one = (data_size == 8 ? __builtin_bswap32(*current--) : *current++) ^ *reg; + bpf_trace_message("CRC32: data dword: %x\n", *current); + u32 two = (data_size == 8 ? __builtin_bswap32(*current--) : *current++); + lookup_key = (one & 0x000000FF); + lookup_value8 = crc32_table[(u16)(1792 + (u8)lookup_key)]; + lookup_key = (one >> 8) & 0x000000FF; + lookup_value7 = crc32_table[(u16)(1536 + (u8)lookup_key)]; + lookup_key = (one >> 16) & 0x000000FF; + lookup_value6 = crc32_table[(u16)(1280 + (u8)lookup_key)]; + lookup_key = one >> 24; + lookup_value5 = crc32_table[(u16)(1024 + (u8)(lookup_key))]; + lookup_key = (two & 0x000000FF); + lookup_value4 = crc32_table[(u16)(768 + (u8)lookup_key)]; + lookup_key = (two >> 8) & 0x000000FF; + lookup_value3 = crc32_table[(u16)(512 + (u8)lookup_key)]; + lookup_key = (two >> 16) & 0x000000FF; + lookup_value2 = crc32_table[(u16)(256 + (u8)lookup_key)]; + lookup_key = two >> 24; + lookup_value1 = crc32_table[(u8)(lookup_key)]; + *reg = lookup_value8 ^ lookup_value7 ^ lookup_value6 ^ lookup_value5 ^ + lookup_value4 ^ lookup_value3 ^ lookup_value2 ^ lookup_value1; + tmp += 8; + } + volatile int std_algo_lookup_key = 0; + if (data_size < 8) { + unsigned char *currentChar = (unsigned char *) current; + currentChar += data_size - 1; + for (u16 i = tmp; i < data_size; i++) { + bpf_trace_message("CRC32: data byte: %x\n", *currentChar); + std_algo_lookup_key = (u32)(((*reg) & 0xFF) ^ *currentChar--); + if (std_algo_lookup_key >= 0) { + lookup_value = crc32_table[(u8)(std_algo_lookup_key & 255)]; + } + *reg = ((*reg) >> 8) ^ lookup_value; + } + } else { + /* Consume data not processed by slice-by-8 algorithm above, these data are in network byte order */ + unsigned char *currentChar = (unsigned char *) current; + for (u16 i = tmp; i < data_size; i++) { + bpf_trace_message("CRC32: data byte: %x\n", *currentChar); + std_algo_lookup_key = (u32)(((*reg) & 0xFF) ^ *currentChar++); + if (std_algo_lookup_key >= 0) { + lookup_value = crc32_table[(u8)(std_algo_lookup_key & 255)]; + } + *reg = ((*reg) >> 8) ^ lookup_value; + } + } + } +} +static __always_inline u32 crc32_finalize(u32 reg) { + return reg ^ 0xFFFFFFFF; +} diff --git a/testdata/p4tc_samples_outputs/ipip_parser.h b/testdata/p4tc_samples_outputs/ipip_parser.h index bbf38468db2..20fb054f057 100644 --- a/testdata/p4tc_samples_outputs/ipip_parser.h +++ b/testdata/p4tc_samples_outputs/ipip_parser.h @@ -157,11 +157,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/matchtype_parser.h b/testdata/p4tc_samples_outputs/matchtype_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/matchtype_parser.h +++ b/testdata/p4tc_samples_outputs/matchtype_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h b/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h +++ b/testdata/p4tc_samples_outputs/mix_matchtype_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 347a85d3865..5c8a19c1a88 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_01_parser.h @@ -167,11 +167,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 347a85d3865..5c8a19c1a88 100644 --- a/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.h +++ b/testdata/p4tc_samples_outputs/multiple_tables_example_02_parser.h @@ -167,11 +167,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/name_annotation_example_parser.h b/testdata/p4tc_samples_outputs/name_annotation_example_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/name_annotation_example_parser.h +++ b/testdata/p4tc_samples_outputs/name_annotation_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/no_table_example_parser.h b/testdata/p4tc_samples_outputs/no_table_example_parser.h index 3ce34d64848..b65ae62b59a 100644 --- a/testdata/p4tc_samples_outputs/no_table_example_parser.h +++ b/testdata/p4tc_samples_outputs/no_table_example_parser.h @@ -161,11 +161,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/noaction_example_01_parser.h b/testdata/p4tc_samples_outputs/noaction_example_01_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_01_parser.h +++ b/testdata/p4tc_samples_outputs/noaction_example_01_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/noaction_example_02_parser.h b/testdata/p4tc_samples_outputs/noaction_example_02_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/noaction_example_02_parser.h +++ b/testdata/p4tc_samples_outputs/noaction_example_02_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h b/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h index 7f7c95824d3..d0f8789a8f6 100644 --- a/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h +++ b/testdata/p4tc_samples_outputs/nummask_annotation_example_parser.h @@ -167,11 +167,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/send_to_port_example_parser.h +++ b/testdata/p4tc_samples_outputs/send_to_port_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.h +++ b/testdata/p4tc_samples_outputs/set_entry_timer_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/simple_exact_example_parser.h b/testdata/p4tc_samples_outputs/simple_exact_example_parser.h index a67ccde435a..7c722359cc5 100644 --- a/testdata/p4tc_samples_outputs/simple_exact_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_exact_example_parser.h @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/simple_extern_example_parser.h b/testdata/p4tc_samples_outputs/simple_extern_example_parser.h index 7843238b346..808992488d7 100644 --- a/testdata/p4tc_samples_outputs/simple_extern_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_extern_example_parser.h @@ -159,11 +159,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h b/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h index a67ccde435a..7c722359cc5 100644 --- a/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_lpm_example_parser.h @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h b/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h index a67ccde435a..7c722359cc5 100644 --- a/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h +++ b/testdata/p4tc_samples_outputs/simple_ternary_example_parser.h @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/size_param_example_parser.h b/testdata/p4tc_samples_outputs/size_param_example_parser.h index 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/size_param_example_parser.h +++ b/testdata/p4tc_samples_outputs/size_param_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 db9bf51e36a..7a99d4144a5 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 @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 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 @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 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 @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 0c06ab82476..743fd5363a3 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 @@ -154,11 +154,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 48e706ed208..3b6f75c5980 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 @@ -154,11 +154,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 61a32160edb..d8475cf3118 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 @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 db9bf51e36a..7a99d4144a5 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 @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 db9bf51e36a..7a99d4144a5 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 @@ -155,11 +155,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 2d42144bb52..90ff839fc9f 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 @@ -154,11 +154,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} 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 11d6b2e6fea..54a8b788e1b 100644 --- a/testdata/p4tc_samples_outputs/tc_type_annotation_example_parser.h +++ b/testdata/p4tc_samples_outputs/tc_type_annotation_example_parser.h @@ -153,11 +153,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -} diff --git a/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h b/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h index 7f57f60ba5c..2a658bc386b 100644 --- a/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h +++ b/testdata/p4tc_samples_outputs/test_ipv6_example_parser.h @@ -164,11 +164,3 @@ void crc32_update(u32 * reg, const u8 * data, u16 data_size, const u32 poly) { static __always_inline u32 crc32_finalize(u32 reg) { return reg ^ 0xFFFFFFFF; } -inline u16 csum16_add(u16 csum, u16 addend) { - u16 res = csum; - res += addend; - return (res + (res < addend)); -} -inline u16 csum16_sub(u16 csum, u16 addend) { - return csum16_add(csum, ~addend); -}