Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for parser errors in tc backend #4443

Merged
merged 2 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 39 additions & 21 deletions backends/tc/ebpfCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,24 @@ void EBPFPnaParser::emit(EBPF::CodeBuilder *builder) {
builder->blockEnd(true);
}

void EBPFPnaParser::emitRejectState(EBPF::CodeBuilder *builder) {
builder->emitIndent();
builder->appendFormat("if (%s == 0) ", program->errorVar.c_str());
builder->blockStart();
builder->target->emitTraceMessage(
builder, "Parser: Explicit transition to reject state, dropping packet..");
builder->emitIndent();
builder->appendFormat("return %s", builder->target->abortReturnCode().c_str());
builder->endOfStatement(true);
builder->blockEnd(true);
builder->emitIndent();
builder->appendFormat("compiler_meta__->parser_error = %s", program->errorVar.c_str());
builder->endOfStatement(true);
builder->emitIndent();
builder->appendFormat("goto %s", IR::ParserState::accept.c_str());
builder->endOfStatement(true);
}

// This code is similar to compileExtractField function in PsaStateTranslationVisitor.
// Handled TC "macaddr" annotation.
void PnaStateTranslationVisitor::compileExtractField(const IR::Expression *expr,
Expand Down Expand Up @@ -1323,6 +1341,26 @@ ControlBodyTranslatorPNA::ControlBodyTranslatorPNA(const EBPF::EBPFControlPSA *c
EBPF::ControlBodyTranslator(control),
tcIR(tcIR) {}

bool ControlBodyTranslatorPNA::preorder(const IR::Member *m) {
if ((m->expr != nullptr) && (m->expr->type != nullptr)) {
if (auto st = m->expr->type->to<IR::Type_Struct>()) {
if (st->name == "pna_main_input_metadata_t") {
if (m->member.name == "input_port") {
builder->append("skb->ifindex");
return false;
} else if (m->member.name == "parser_error") {
builder->append("compiler_meta__->parser_error");
return false;
} else {
::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
"%1%: this metadata field is not supported", m);
}
}
}
}
return CodeGenInspector::preorder(m);
usha1830 marked this conversation as resolved.
Show resolved Hide resolved
}

ControlBodyTranslatorPNA::ControlBodyTranslatorPNA(const EBPF::EBPFControlPSA *control,
const ConvertToBackendIR *tcIR,
const EBPF::EBPFTablePSA *table)
Expand All @@ -1335,17 +1373,6 @@ cstring ControlBodyTranslatorPNA::getParamName(const IR::PathExpression *expr) {
return expr->path->name.name;
}

bool ControlBodyTranslatorPNA::checkPnaPortMem(const IR::Member *m) {
if (m->expr != nullptr && m->expr->type != nullptr) {
if (auto str_type = m->expr->type->to<IR::Type_Struct>()) {
if (str_type->name == "pna_main_input_metadata_t" && m->member.name == "input_port") {
return true;
}
}
}
return false;
}

void ControlBodyTranslatorPNA::processFunction(const P4::ExternFunction *function) {
if (function->expr->method->toString() == "send_to_port" ||
function->expr->method->toString() == "drop_packet") {
Expand All @@ -1360,12 +1387,7 @@ void ControlBodyTranslatorPNA::processFunction(const P4::ExternFunction *functio
for (auto a : *function->expr->arguments) {
if (!first) builder->append(", ");
first = false;
if (a->expression->is<IR::Member>() &&
checkPnaPortMem(a->expression->to<IR::Member>())) {
builder->append("skb->ifindex");
} else {
visit(a);
}
visit(a);
}
builder->append(")");
return;
Expand Down Expand Up @@ -1482,16 +1504,12 @@ void ControlBodyTranslatorPNA::processApply(const P4::ApplyMethod *method) {
}
}

auto mem = c->expression->to<IR::Member>();
builder->emitIndent();
if (memcpy) {
builder->appendFormat("__builtin_memcpy(&(%s.%s[0]), &(", keyname.c_str(),
fieldName.c_str());
table->codeGen->visit(c->expression);
builder->appendFormat("[0]), %d)", scalar->bytesRequired());
} else if (mem && checkPnaPortMem(mem)) {
builder->appendFormat("%s.%s = ", keyname.c_str(), fieldName.c_str());
builder->append("skb->ifindex");
} else {
builder->appendFormat("%s.%s = ", keyname.c_str(), fieldName.c_str());
if (isLPMKeyBigEndian) builder->appendFormat("%s(", swap.c_str());
Expand Down
2 changes: 2 additions & 0 deletions backends/tc/ebpfCodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class EBPFPnaParser : public EBPF::EBPFPsaParser {
EBPFPnaParser(const EBPF::EBPFProgram *program, const IR::ParserBlock *block,
const P4::TypeMap *typeMap);
void emit(EBPF::CodeBuilder *builder) override;
void emitRejectState(EBPF::CodeBuilder *) override;

DECLARE_TYPEINFO(EBPFPnaParser, EBPF::EBPFPsaParser);
};
Expand Down Expand Up @@ -319,6 +320,7 @@ class ControlBodyTranslatorPNA : public EBPF::ControlBodyTranslator {
virtual cstring getParamName(const IR::PathExpression *);
bool preorder(const IR::AssignmentStatement *a) override;
void processMethod(const P4::ExternMethod *method) override;
bool preorder(const IR::Member *) override;
};

// Similar to class ActionTranslationVisitorPSA in backends/ebpf/psa/ebpfPsaControl.h
Expand Down
1 change: 1 addition & 0 deletions backends/tc/runtime/pna.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct pna_global_metadata {
PortId_t egress_port;
enum MirrorType mirror_type;
MirrorSlotId_t mirror_slot_id;
ParserError_t parser_error;
MirrorSessionId_t mirror_session_id;
__u8 mark;
bool pass_to_kernel; // internal metadata, forces sending packet up to kernel stack
Expand Down
10 changes: 5 additions & 5 deletions testdata/p4tc_samples_outputs/calculator_control_blocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ if (/* hdr->p4calc.isValid() */
tmp_5 = hdr->ethernet.dstAddr;
hdr->ethernet.dstAddr = hdr->ethernet.srcAddr;
hdr->ethernet.srcAddr = tmp_5;
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand All @@ -103,7 +103,7 @@ if (/* hdr->p4calc.isValid() */
tmp_5 = hdr->ethernet.dstAddr;
hdr->ethernet.dstAddr = hdr->ethernet.srcAddr;
hdr->ethernet.srcAddr = tmp_5;
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand All @@ -114,7 +114,7 @@ if (/* hdr->p4calc.isValid() */
tmp_5 = hdr->ethernet.dstAddr;
hdr->ethernet.dstAddr = hdr->ethernet.srcAddr;
hdr->ethernet.srcAddr = tmp_5;
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand All @@ -125,7 +125,7 @@ if (/* hdr->p4calc.isValid() */
tmp_5 = hdr->ethernet.dstAddr;
hdr->ethernet.dstAddr = hdr->ethernet.srcAddr;
hdr->ethernet.srcAddr = tmp_5;
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand All @@ -136,7 +136,7 @@ if (/* hdr->p4calc.isValid() */
tmp_5 = hdr->ethernet.dstAddr;
hdr->ethernet.dstAddr = hdr->ethernet.srcAddr;
hdr->ethernet.srcAddr = tmp_5;
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/calculator_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/checksum_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ ck_0_state; goto accept;
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct Header_t *h,
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/drop_packet_example_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/hash1_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/ipip_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/matchtype_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ if (hdr->ipv4.protocol == 6 || ((hdr->ipv4.version > 1) && (hdr->ipv4.ihl <= 2))
switch (value->action) {
case MAINCONTROLIMPL_IPV4_TBL_3_ACT_MAINCONTROLIMPL_SENDTOPORT:
{
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand Down Expand Up @@ -377,7 +377,7 @@ if (hdr->ipv4.protocol == 6 || ((hdr->ipv4.version > 1) && (hdr->ipv4.ihl <= 2))
switch (value->action) {
case MAINCONTROLIMPL_IPV4_TBL_4_ACT_MAINCONTROLIMPL_SENDTOPORT:
{
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand Down Expand Up @@ -539,7 +539,7 @@ if (hdr->ipv4.protocol != 6) {
break;
case MAINCONTROLIMPL_SET_ALL_OPTIONS_ACT_MAINCONTROLIMPL_SENDTOPORT:
{
/* send_to_port(istd.input_port) */
/* send_to_port(skb->ifindex) */
compiler_meta__->drop = false;
send_to_port(skb->ifindex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr,
{
u8 hit;
{
if ((u32)istd.input_port == 4) {
if ((u32)skb->ifindex == 4) {
hdr->udp.src_port = (hdr->udp.src_port + 1); }

}
Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/no_table_example_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/noaction_example_01_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/noaction_example_02_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr,
{
u8 hit;
{
if (((u32)istd.input_port == 2 && /* hdr->ipv4.isValid() */
if (((u32)skb->ifindex == 2 && /* hdr->ipv4.isValid() */
hdr->ipv4.ebpf_valid) && /* hdr->tcp.isValid() */
hdr->tcp.ebpf_valid) {
/* set_ct_options_0.apply() */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
1 change: 1 addition & 0 deletions testdata/p4tc_samples_outputs/simple_lpm_example_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static __always_inline int run_parser(struct __sk_buff *skb, struct my_ingress_h
if (ebpf_errorCode == 0) {
return TC_ACT_SHOT;
}
compiler_meta__->parser_error = ebpf_errorCode;
goto accept;
}

Expand Down
Loading
Loading