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

[Draft] - Align key components to the nearest 8-bit size #30

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

komaljai
Copy link
Owner

@komaljai komaljai commented Oct 3, 2024

No description provided.

@komaljai komaljai changed the title Align key components to the nearest 8-bit size [Draft] - Align key components to the nearest 8-bit size Oct 3, 2024
Copy link

@vbnogueira vbnogueira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found some small issues, but the general idea of storePrimitive* and getPrimitive* makes sense

However, I have a question.
In cases where you have something like a bit<22>.
Is getPrimitive32's first parameter guaranteed to be zeroed out?
Analogously, is the second parameter of storePrimitive32 (u32 value) guaranteed to have the remaining 10 bits zeroed out?

If it is, I think there is no issue, otherwise masking or shifting should be necessary

a[2] = (u8)(value >> 16);
a[3] = (u8)(value >> 24);
a[4] = (u8)(value >> 32);
if (size < 48) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm misunderstanding, but shouldn't it be:

Suggested change
if (size < 48) {
if (size >= 48) {

You'd want to get the sixth byte if the size is bigger >= 48

if (size < 48) {
a[5] = (u8)(value >> 40);
}
if (size < 56){

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same thing would apply for the seventh byte

@@ -65,6 +65,39 @@ REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2)
BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md)
REGISTER_END()

u32 getPrimitive32(u8 *a, int size) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can remove size

Comment on lines +71 to +81
u64 getPrimitive64(u8 *a, int size) {
if(size < 40) {
return ((a[4] << 32) | (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
} else {
if(size < 48) {
return ((a[5] << 40) | (a[4] << 32) | (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
} else {
return ((a[6] << 48) | (a[5] << 40) | (a[4] << 32) | (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to avoid the warnings

Suggested change
u64 getPrimitive64(u8 *a, int size) {
if(size < 40) {
return ((a[4] << 32) | (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
} else {
if(size < 48) {
return ((a[5] << 40) | (a[4] << 32) | (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
} else {
return ((a[6] << 48) | (a[5] << 40) | (a[4] << 32) | (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
}
}
}
u64 getPrimitive64(u8 *a, int size) {
if(size < 40) {
return (((((u64)a[4]) << 32)) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]);
} else {
if(size < 48) {
return ((((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]);
} else {
return ((((u64)a[6]) << 48) | (((u64)a[5]) << 40) | (((u64)a[4]) << 32) | (((u64)a[3]) << 24) | (((u64)a[2]) << 16) | (((u64)a[1]) << 8) | a[0]);
}
}
}

Comment on lines +68 to +70
u32 getPrimitive32(u8 *a, int size) {
return ((a[2]<<16) | (a[1] << 8) | a[0]);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to avoid the warnings

Suggested change
u32 getPrimitive32(u8 *a, int size) {
return ((a[2]<<16) | (a[1] << 8) | a[0]);
}
u32 getPrimitive32(u8 *a) {
return ((((u32)a[2]) << 16) | (((u32)a[1]) << 8) | a[0]);
}

@@ -114,8 +114,8 @@ if (/* hdr->ipv4.isValid() */
break;
case MAINCONTROLIMPL_IPV4_TBL_1_ACT_MAINCONTROLIMPL_SEND_NH:
{
hdr->ethernet.srcAddr = bpf_cpu_to_be64(value->u.MainControlImpl_send_nh.smac);
hdr->ethernet.dstAddr = ntohll(value->u.MainControlImpl_send_nh.dmac << 16);
storePrimitive64(&hdr->ethernet.srcAddr, 48, (bpf_cpu_to_be64(value->u.MainControlImpl_send_nh.smac)));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I accidentally found a bug
Was testing changing EthernetAddress' typecast[1] to a bit<39> and saw that the generated code was outputing this line as:

storePrimitive64(&hdr->ethernet.srcAddr, 40, (bpf_cpu_to_be64((u64)(u64)value->u.MainControlImpl_send_nh.smac)));

From what I understood, the second argument should be 39, not 40

[1] https://github.com/p4lang/p4c/blob/main/testdata/p4tc_samples/add_entry_1_example.p4#L4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants