summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2024-04-14 20:55:28 -0700
committerMaciej Żenczykowski <maze@google.com>2024-04-14 21:32:02 -0700
commitd05ec9709294678d91e1754fb7121aca399724f8 (patch)
tree086928602e6a41601567f62c9f7b5e3d27bb4373
parent02ad33821835fd2e9ed439832efd23dae52e56ff (diff)
downloadapf-d05ec9709294678d91e1754fb7121aca399724f8.tar.gz
v5: reduce number of var declarations after statements
Trying to get us closer to being able to remove -Wno-declaration-after-statement Doing a small part only, for early feedback on approach... Test: TreeHugger, manually Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: Ia9fb1e14e374ed7f4b23cd87611a75de9904cd17
-rw-r--r--apf_dns.h17
-rw-r--r--v5/apf_interpreter.c150
-rw-r--r--v5/apf_interpreter_source.c133
3 files changed, 164 insertions, 136 deletions
diff --git a/apf_dns.h b/apf_dns.h
index db7f724..c293d5e 100644
--- a/apf_dns.h
+++ b/apf_dns.h
@@ -23,13 +23,16 @@ FUNC(match_result_type match_single_name(const u8* needle,
/* DNS names are <= 255 characters including terminating 0, since >= 1 char + '.' per level => max. 127 levels */
for (lvl = 1; lvl <= 127; ++lvl) {
+ u8 v;
if (*ofs >= udp_len) return error_packet;
- u8 v = udp[(*ofs)++];
+ v = udp[(*ofs)++];
if (v >= 0xC0) { /* RFC 1035 4.1.4 - handle message compression */
+ u8 w;
+ u32 new_ofs;
if (*ofs >= udp_len) return error_packet;
- u8 w = udp[(*ofs)++];
+ w = udp[(*ofs)++];
if (*ofs > first_unread_offset) first_unread_offset = *ofs;
- u32 new_ofs = (v - 0xC0) * 256u + w;
+ new_ofs = (v - 0xC0) * 256u + w;
if (new_ofs >= *ofs) return error_packet; /* RFC 1035 4.1.4 allows only backward pointers */
*ofs = new_ofs;
} else if (v > 63) {
@@ -80,18 +83,18 @@ FUNC(match_result_type match_names(const u8* needles,
const u8* const udp,
const u32 udp_len,
const int question_type)) {
+ u32 num_questions, num_answers;
if (udp_len < 12) return error_packet; /* lack of dns header */
/* dns header: be16 tid, flags, num_{questions,answers,authority,additional} */
- u32 num_questions = read_be16(udp + 4);
- u32 num_answers = read_be16(udp + 6) + read_be16(udp + 8) + read_be16(udp + 10);
+ num_questions = read_be16(udp + 4);
+ num_answers = read_be16(udp + 6) + read_be16(udp + 8) + read_be16(udp + 10);
/* loop until we hit final needle, which is a null byte */
while (true) {
+ u32 i, ofs = 12; /* dns header is 12 bytes */
if (needles >= needle_bound) return error_program;
if (!*needles) return nomatch; /* we've run out of needles without finding a match */
- u32 ofs = 12; /* dns header is 12 bytes */
- u32 i;
/* match questions */
for (i = 0; i < num_questions; ++i) {
match_result_type m = match_single_name(needles, needle_bound, udp, udp_len, &ofs);
diff --git a/v5/apf_interpreter.c b/v5/apf_interpreter.c
index 1ec14c6..165e3a6 100644
--- a/v5/apf_interpreter.c
+++ b/v5/apf_interpreter.c
@@ -399,13 +399,16 @@ FUNC(match_result_type apf_internal_match_single_name(const u8* needle,
/* DNS names are <= 255 characters including terminating 0, since >= 1 char + '.' per level => max. 127 levels */
for (lvl = 1; lvl <= 127; ++lvl) {
+ u8 v;
if (*ofs >= udp_len) return error_packet;
- u8 v = udp[(*ofs)++];
+ v = udp[(*ofs)++];
if (v >= 0xC0) { /* RFC 1035 4.1.4 - handle message compression */
+ u8 w;
+ u32 new_ofs;
if (*ofs >= udp_len) return error_packet;
- u8 w = udp[(*ofs)++];
+ w = udp[(*ofs)++];
if (*ofs > first_unread_offset) first_unread_offset = *ofs;
- u32 new_ofs = (v - 0xC0) * 256u + w;
+ new_ofs = (v - 0xC0) * 256u + w;
if (new_ofs >= *ofs) return error_packet; /* RFC 1035 4.1.4 allows only backward pointers */
*ofs = new_ofs;
} else if (v > 63) {
@@ -456,18 +459,18 @@ FUNC(match_result_type apf_internal_match_names(const u8* needles,
const u8* const udp,
const u32 udp_len,
const int question_type)) {
+ u32 num_questions, num_answers;
if (udp_len < 12) return error_packet; /* lack of dns header */
/* dns header: be16 tid, flags, num_{questions,answers,authority,additional} */
- u32 num_questions = read_be16(udp + 4);
- u32 num_answers = read_be16(udp + 6) + read_be16(udp + 8) + read_be16(udp + 10);
+ num_questions = read_be16(udp + 4);
+ num_answers = read_be16(udp + 6) + read_be16(udp + 8) + read_be16(udp + 10);
/* loop until we hit final needle, which is a null byte */
while (True) {
+ u32 i, ofs = 12; /* dns header is 12 bytes */
if (needles >= needle_bound) return error_program;
if (!*needles) return nomatch; /* we've run out of needles without finding a match */
- u32 ofs = 12; /* dns header is 12 bytes */
- u32 i;
/* match questions */
for (i = 0; i < num_questions; ++i) {
match_result_type m = apf_internal_match_single_name(needles, needle_bound, udp, udp_len, &ofs);
@@ -878,15 +881,7 @@ static int do_apf_run(apf_context* ctx) {
memset(ctx->tx_buf, 0, ctx->tx_buf_len);
ctx->mem.named.tx_buf_offset = 0;
break;
- case TRANSMIT_EXT_OPCODE:
- ASSERT_RETURN(ctx->tx_buf);
- u32 pkt_len = ctx->mem.named.tx_buf_offset;
- /* If pkt_len > allocate_buffer_len, it means sth. wrong */
- /* happened and the tx_buf should be deallocated. */
- if (pkt_len > ctx->tx_buf_len) {
- do_discard_buffer(ctx);
- return EXCEPTION;
- }
+ case TRANSMIT_EXT_OPCODE: {
/* tx_buf_len cannot be large because we'd run out of RAM, */
/* so the above unsigned comparison effectively guarantees casting pkt_len */
/* to a signed value does not result in it going negative. */
@@ -894,31 +889,42 @@ static int do_apf_run(apf_context* ctx) {
u8 csum_ofs = DECODE_U8(); /* 3rd imm, at worst 6 B past prog_len */
u8 csum_start = 0;
u16 partial_csum = 0;
+ u32 pkt_len = ctx->mem.named.tx_buf_offset;
+ ASSERT_RETURN(ctx->tx_buf);
+ /* If pkt_len > allocate_buffer_len, it means sth. wrong */
+ /* happened and the tx_buf should be deallocated. */
+ if (pkt_len > ctx->tx_buf_len) {
+ do_discard_buffer(ctx);
+ return EXCEPTION;
+ }
if (csum_ofs < 255) {
csum_start = DECODE_U8(); /* 4th imm, at worst 7 B past prog_len */
partial_csum = decode_be16(ctx); /* 5th imm, at worst 9 B past prog_len */
}
- int dscp = apf_internal_csum_and_return_dscp(ctx->tx_buf, (s32)pkt_len, ip_ofs,
- partial_csum, csum_start, csum_ofs,
- (Boolean)reg_num);
- int ret = apf_internal_do_transmit_buffer(ctx, pkt_len, dscp);
- if (ret) { counter[-4]++; return EXCEPTION; } /* transmit failure */
+ {
+ int dscp = apf_internal_csum_and_return_dscp(ctx->tx_buf, (s32)pkt_len, ip_ofs,
+ partial_csum, csum_start, csum_ofs,
+ (Boolean)reg_num);
+ int ret = apf_internal_do_transmit_buffer(ctx, pkt_len, dscp);
+ if (ret) { counter[-4]++; return EXCEPTION; } /* transmit failure */
+ }
break;
+ }
case EPKTDATACOPYIMM_EXT_OPCODE: /* 41 */
case EPKTDATACOPYR1_EXT_OPCODE: /* 42 */
pktcopy_src_offset = ctx->R[0];
FALLTHROUGH;
case PKTDATACOPYIMM_EXT_OPCODE: { /* 65536 */
+ u32 dst_offs = ctx->mem.named.tx_buf_offset;
u32 copy_len = ctx->R[1];
if (imm != EPKTDATACOPYR1_EXT_OPCODE) {
copy_len = DECODE_U8(); /* 2nd imm, at worst 8 bytes past prog_len */
}
ASSERT_RETURN(ctx->tx_buf);
- u32 dst_offs = ctx->mem.named.tx_buf_offset;
ASSERT_IN_OUTPUT_BOUNDS(dst_offs, copy_len);
if (reg_num == 0) { /* copy from packet */
- ASSERT_IN_PACKET_BOUNDS(pktcopy_src_offset);
const u32 last_packet_offs = pktcopy_src_offset + copy_len - 1;
+ ASSERT_IN_PACKET_BOUNDS(pktcopy_src_offset);
ASSERT_RETURN(last_packet_offs >= pktcopy_src_offset);
ASSERT_IN_PACKET_BOUNDS(last_packet_offs);
memcpy(ctx->tx_buf + dst_offs, ctx->packet + pktcopy_src_offset, copy_len);
@@ -940,33 +946,35 @@ static int do_apf_run(apf_context* ctx) {
if (imm & 1) { /* JDNSQMATCH & JDNSQMATCHSAFE are *odd* extended opcodes */
qtype = DECODE_U8(); /* 3rd imm, at worst 9 bytes past prog_len */
}
- u32 udp_payload_offset = ctx->R[0];
- match_result_type match_rst = apf_internal_match_names(ctx->program + ctx->pc,
- ctx->program + ctx->program_len,
- ctx->packet + udp_payload_offset,
- ctx->packet_len - udp_payload_offset,
- qtype);
- if (match_rst == error_program) return EXCEPTION;
- if (match_rst == error_packet) {
- counter[-5]++; /* increment error dns packet counter */
- return (imm >= JDNSQMATCHSAFE_EXT_OPCODE) ? PASS : DROP;
- }
- while (ctx->pc + 1 < ctx->program_len &&
- (ctx->program[ctx->pc] || ctx->program[ctx->pc + 1])) {
- ctx->pc++;
+ {
+ u32 udp_payload_offset = ctx->R[0];
+ match_result_type match_rst = apf_internal_match_names(ctx->program + ctx->pc,
+ ctx->program + ctx->program_len,
+ ctx->packet + udp_payload_offset,
+ ctx->packet_len - udp_payload_offset,
+ qtype);
+ if (match_rst == error_program) return EXCEPTION;
+ if (match_rst == error_packet) {
+ counter[-5]++; /* increment error dns packet counter */
+ return (imm >= JDNSQMATCHSAFE_EXT_OPCODE) ? PASS : DROP;
+ }
+ while (ctx->pc + 1 < ctx->program_len &&
+ (ctx->program[ctx->pc] || ctx->program[ctx->pc + 1])) {
+ ctx->pc++;
+ }
+ ctx->pc += 2; /* skip the final double 0 needle end */
+ /* relies on reg_num in {0,1} and match_rst being {False=0, True=1} */
+ if (!(reg_num ^ (u32)match_rst)) ctx->pc += jump_offs;
}
- ctx->pc += 2; /* skip the final double 0 needle end */
- /* relies on reg_num in {0,1} and match_rst being {False=0, True=1} */
- if (!(reg_num ^ (u32)match_rst)) ctx->pc += jump_offs;
break;
}
case EWRITE1_EXT_OPCODE:
case EWRITE2_EXT_OPCODE:
case EWRITE4_EXT_OPCODE: {
- ASSERT_RETURN(ctx->tx_buf);
const u32 write_len = 1 << (imm - EWRITE1_EXT_OPCODE);
- ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
u32 i;
+ ASSERT_RETURN(ctx->tx_buf);
+ ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
for (i = 0; i < write_len; ++i) {
ctx->tx_buf[ctx->mem.named.tx_buf_offset++] =
(u8)(REG >> (write_len - 1 - i) * 8);
@@ -1006,12 +1014,12 @@ static int do_apf_run(apf_context* ctx) {
counter[-(s32)imm] = REG;
}
} else {
+ u32 size = 4;
u32 offs = OTHER_REG + (u32)signed_imm;
/* Negative offsets wrap around the end of the address space. */
/* This allows us to efficiently access the end of the */
/* address space with one-byte immediates without using %=. */
if (offs & 0x80000000) offs += ctx->ram_len; /* unsigned overflow intended */
- u32 size = 4;
ASSERT_IN_DATA_BOUNDS(offs, size);
if (opcode == LDDW_OPCODE) {
u32 val = 0;
@@ -1029,12 +1037,14 @@ static int do_apf_run(apf_context* ctx) {
case WRITE_OPCODE: {
ASSERT_RETURN(ctx->tx_buf);
ASSERT_RETURN(len_field);
- const u32 write_len = 1 << (len_field - 1);
- ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
- u32 i;
- for (i = 0; i < write_len; ++i) {
- ctx->tx_buf[ctx->mem.named.tx_buf_offset++] =
- (u8)(imm >> (write_len - 1 - i) * 8);
+ {
+ const u32 write_len = 1 << (len_field - 1);
+ u32 i;
+ ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
+ for (i = 0; i < write_len; ++i) {
+ ctx->tx_buf[ctx->mem.named.tx_buf_offset++] =
+ (u8)(imm >> (write_len - 1 - i) * 8);
+ }
}
break;
}
@@ -1062,24 +1072,28 @@ int apf_run(void* ctx, u32* const program, const u32 program_len,
if (!packet) return EXCEPTION;
if (packet_len < ETH_HLEN) return EXCEPTION;
- apf_context apf_ctx = { 0 };
- apf_ctx.caller_ctx = ctx;
- apf_ctx.program = (u8*)program;
- apf_ctx.program_len = program_len;
- apf_ctx.ram_len = ram_len;
- apf_ctx.packet = packet;
- apf_ctx.packet_len = packet_len;
- /* Fill in pre-filled memory slot values. */
- apf_ctx.mem.named.program_size = program_len;
- apf_ctx.mem.named.ram_len = ram_len;
- apf_ctx.mem.named.packet_size = packet_len;
- apf_ctx.mem.named.apf_version = apf_version();
- apf_ctx.mem.named.filter_age = filter_age_16384ths >> 14;
- apf_ctx.mem.named.filter_age_16384ths = filter_age_16384ths;
+ {
+ apf_context apf_ctx = { 0 };
+ int ret;
- int ret = do_apf_run(&apf_ctx);
- if (apf_ctx.tx_buf) do_discard_buffer(&apf_ctx);
- /* Convert any exceptions internal to the program to just normal 'PASS' */
- if (ret >= EXCEPTION) ret = PASS;
- return ret;
+ apf_ctx.caller_ctx = ctx;
+ apf_ctx.program = (u8*)program;
+ apf_ctx.program_len = program_len;
+ apf_ctx.ram_len = ram_len;
+ apf_ctx.packet = packet;
+ apf_ctx.packet_len = packet_len;
+ /* Fill in pre-filled memory slot values. */
+ apf_ctx.mem.named.program_size = program_len;
+ apf_ctx.mem.named.ram_len = ram_len;
+ apf_ctx.mem.named.packet_size = packet_len;
+ apf_ctx.mem.named.apf_version = apf_version();
+ apf_ctx.mem.named.filter_age = filter_age_16384ths >> 14;
+ apf_ctx.mem.named.filter_age_16384ths = filter_age_16384ths;
+
+ ret = do_apf_run(&apf_ctx);
+ if (apf_ctx.tx_buf) do_discard_buffer(&apf_ctx);
+ /* Convert any exceptions internal to the program to just normal 'PASS' */
+ if (ret >= EXCEPTION) ret = PASS;
+ return ret;
+ }
}
diff --git a/v5/apf_interpreter_source.c b/v5/apf_interpreter_source.c
index a515964..fd2c205 100644
--- a/v5/apf_interpreter_source.c
+++ b/v5/apf_interpreter_source.c
@@ -348,15 +348,7 @@ static int do_apf_run(apf_context* ctx) {
memset(ctx->tx_buf, 0, ctx->tx_buf_len);
ctx->mem.named.tx_buf_offset = 0;
break;
- case TRANSMIT_EXT_OPCODE:
- ASSERT_RETURN(ctx->tx_buf);
- u32 pkt_len = ctx->mem.named.tx_buf_offset;
- // If pkt_len > allocate_buffer_len, it means sth. wrong
- // happened and the tx_buf should be deallocated.
- if (pkt_len > ctx->tx_buf_len) {
- do_discard_buffer(ctx);
- return EXCEPTION;
- }
+ case TRANSMIT_EXT_OPCODE: {
// tx_buf_len cannot be large because we'd run out of RAM,
// so the above unsigned comparison effectively guarantees casting pkt_len
// to a signed value does not result in it going negative.
@@ -364,31 +356,42 @@ static int do_apf_run(apf_context* ctx) {
u8 csum_ofs = DECODE_U8(); // 3rd imm, at worst 6 B past prog_len
u8 csum_start = 0;
u16 partial_csum = 0;
+ u32 pkt_len = ctx->mem.named.tx_buf_offset;
+ ASSERT_RETURN(ctx->tx_buf);
+ // If pkt_len > allocate_buffer_len, it means sth. wrong
+ // happened and the tx_buf should be deallocated.
+ if (pkt_len > ctx->tx_buf_len) {
+ do_discard_buffer(ctx);
+ return EXCEPTION;
+ }
if (csum_ofs < 255) {
csum_start = DECODE_U8(); // 4th imm, at worst 7 B past prog_len
partial_csum = decode_be16(ctx); // 5th imm, at worst 9 B past prog_len
}
- int dscp = csum_and_return_dscp(ctx->tx_buf, (s32)pkt_len, ip_ofs,
- partial_csum, csum_start, csum_ofs,
- (bool)reg_num);
- int ret = do_transmit_buffer(ctx, pkt_len, dscp);
- if (ret) { counter[-4]++; return EXCEPTION; } // transmit failure
+ {
+ int dscp = csum_and_return_dscp(ctx->tx_buf, (s32)pkt_len, ip_ofs,
+ partial_csum, csum_start, csum_ofs,
+ (bool)reg_num);
+ int ret = do_transmit_buffer(ctx, pkt_len, dscp);
+ if (ret) { counter[-4]++; return EXCEPTION; } // transmit failure
+ }
break;
+ }
case EPKTDATACOPYIMM_EXT_OPCODE: // 41
case EPKTDATACOPYR1_EXT_OPCODE: // 42
pktcopy_src_offset = ctx->R[0];
FALLTHROUGH;
case PKTDATACOPYIMM_EXT_OPCODE: { // 65536
+ u32 dst_offs = ctx->mem.named.tx_buf_offset;
u32 copy_len = ctx->R[1];
if (imm != EPKTDATACOPYR1_EXT_OPCODE) {
copy_len = DECODE_U8(); // 2nd imm, at worst 8 bytes past prog_len
}
ASSERT_RETURN(ctx->tx_buf);
- u32 dst_offs = ctx->mem.named.tx_buf_offset;
ASSERT_IN_OUTPUT_BOUNDS(dst_offs, copy_len);
if (reg_num == 0) { // copy from packet
- ASSERT_IN_PACKET_BOUNDS(pktcopy_src_offset);
const u32 last_packet_offs = pktcopy_src_offset + copy_len - 1;
+ ASSERT_IN_PACKET_BOUNDS(pktcopy_src_offset);
ASSERT_RETURN(last_packet_offs >= pktcopy_src_offset);
ASSERT_IN_PACKET_BOUNDS(last_packet_offs);
memcpy(ctx->tx_buf + dst_offs, ctx->packet + pktcopy_src_offset, copy_len);
@@ -410,33 +413,35 @@ static int do_apf_run(apf_context* ctx) {
if (imm & 1) { // JDNSQMATCH & JDNSQMATCHSAFE are *odd* extended opcodes
qtype = DECODE_U8(); // 3rd imm, at worst 9 bytes past prog_len
}
- u32 udp_payload_offset = ctx->R[0];
- match_result_type match_rst = match_names(ctx->program + ctx->pc,
- ctx->program + ctx->program_len,
- ctx->packet + udp_payload_offset,
- ctx->packet_len - udp_payload_offset,
- qtype);
- if (match_rst == error_program) return EXCEPTION;
- if (match_rst == error_packet) {
- counter[-5]++; // increment error dns packet counter
- return (imm >= JDNSQMATCHSAFE_EXT_OPCODE) ? PASS : DROP;
- }
- while (ctx->pc + 1 < ctx->program_len &&
- (ctx->program[ctx->pc] || ctx->program[ctx->pc + 1])) {
- ctx->pc++;
+ {
+ u32 udp_payload_offset = ctx->R[0];
+ match_result_type match_rst = match_names(ctx->program + ctx->pc,
+ ctx->program + ctx->program_len,
+ ctx->packet + udp_payload_offset,
+ ctx->packet_len - udp_payload_offset,
+ qtype);
+ if (match_rst == error_program) return EXCEPTION;
+ if (match_rst == error_packet) {
+ counter[-5]++; // increment error dns packet counter
+ return (imm >= JDNSQMATCHSAFE_EXT_OPCODE) ? PASS : DROP;
+ }
+ while (ctx->pc + 1 < ctx->program_len &&
+ (ctx->program[ctx->pc] || ctx->program[ctx->pc + 1])) {
+ ctx->pc++;
+ }
+ ctx->pc += 2; // skip the final double 0 needle end
+ // relies on reg_num in {0,1} and match_rst being {false=0, true=1}
+ if (!(reg_num ^ (u32)match_rst)) ctx->pc += jump_offs;
}
- ctx->pc += 2; // skip the final double 0 needle end
- // relies on reg_num in {0,1} and match_rst being {false=0, true=1}
- if (!(reg_num ^ (u32)match_rst)) ctx->pc += jump_offs;
break;
}
case EWRITE1_EXT_OPCODE:
case EWRITE2_EXT_OPCODE:
case EWRITE4_EXT_OPCODE: {
- ASSERT_RETURN(ctx->tx_buf);
const u32 write_len = 1 << (imm - EWRITE1_EXT_OPCODE);
- ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
u32 i;
+ ASSERT_RETURN(ctx->tx_buf);
+ ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
for (i = 0; i < write_len; ++i) {
ctx->tx_buf[ctx->mem.named.tx_buf_offset++] =
(u8)(REG >> (write_len - 1 - i) * 8);
@@ -476,12 +481,12 @@ static int do_apf_run(apf_context* ctx) {
counter[-(s32)imm] = REG;
}
} else {
+ u32 size = 4;
u32 offs = OTHER_REG + (u32)signed_imm;
// Negative offsets wrap around the end of the address space.
// This allows us to efficiently access the end of the
// address space with one-byte immediates without using %=.
if (offs & 0x80000000) offs += ctx->ram_len; // unsigned overflow intended
- u32 size = 4;
ASSERT_IN_DATA_BOUNDS(offs, size);
if (opcode == LDDW_OPCODE) {
u32 val = 0;
@@ -499,12 +504,14 @@ static int do_apf_run(apf_context* ctx) {
case WRITE_OPCODE: {
ASSERT_RETURN(ctx->tx_buf);
ASSERT_RETURN(len_field);
- const u32 write_len = 1 << (len_field - 1);
- ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
- u32 i;
- for (i = 0; i < write_len; ++i) {
- ctx->tx_buf[ctx->mem.named.tx_buf_offset++] =
- (u8)(imm >> (write_len - 1 - i) * 8);
+ {
+ const u32 write_len = 1 << (len_field - 1);
+ u32 i;
+ ASSERT_IN_OUTPUT_BOUNDS(ctx->mem.named.tx_buf_offset, write_len);
+ for (i = 0; i < write_len; ++i) {
+ ctx->tx_buf[ctx->mem.named.tx_buf_offset++] =
+ (u8)(imm >> (write_len - 1 - i) * 8);
+ }
}
break;
}
@@ -532,24 +539,28 @@ int apf_run(void* ctx, u32* const program, const u32 program_len,
if (!packet) return EXCEPTION;
if (packet_len < ETH_HLEN) return EXCEPTION;
- apf_context apf_ctx = { 0 };
- apf_ctx.caller_ctx = ctx;
- apf_ctx.program = (u8*)program;
- apf_ctx.program_len = program_len;
- apf_ctx.ram_len = ram_len;
- apf_ctx.packet = packet;
- apf_ctx.packet_len = packet_len;
- // Fill in pre-filled memory slot values.
- apf_ctx.mem.named.program_size = program_len;
- apf_ctx.mem.named.ram_len = ram_len;
- apf_ctx.mem.named.packet_size = packet_len;
- apf_ctx.mem.named.apf_version = apf_version();
- apf_ctx.mem.named.filter_age = filter_age_16384ths >> 14;
- apf_ctx.mem.named.filter_age_16384ths = filter_age_16384ths;
+ {
+ apf_context apf_ctx = { 0 };
+ int ret;
- int ret = do_apf_run(&apf_ctx);
- if (apf_ctx.tx_buf) do_discard_buffer(&apf_ctx);
- // Convert any exceptions internal to the program to just normal 'PASS'
- if (ret >= EXCEPTION) ret = PASS;
- return ret;
+ apf_ctx.caller_ctx = ctx;
+ apf_ctx.program = (u8*)program;
+ apf_ctx.program_len = program_len;
+ apf_ctx.ram_len = ram_len;
+ apf_ctx.packet = packet;
+ apf_ctx.packet_len = packet_len;
+ // Fill in pre-filled memory slot values.
+ apf_ctx.mem.named.program_size = program_len;
+ apf_ctx.mem.named.ram_len = ram_len;
+ apf_ctx.mem.named.packet_size = packet_len;
+ apf_ctx.mem.named.apf_version = apf_version();
+ apf_ctx.mem.named.filter_age = filter_age_16384ths >> 14;
+ apf_ctx.mem.named.filter_age_16384ths = filter_age_16384ths;
+
+ ret = do_apf_run(&apf_ctx);
+ if (apf_ctx.tx_buf) do_discard_buffer(&apf_ctx);
+ // Convert any exceptions internal to the program to just normal 'PASS'
+ if (ret >= EXCEPTION) ret = PASS;
+ return ret;
+ }
}