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

drgn.helpers.linux.net: add some room helpers #353

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
91 changes: 91 additions & 0 deletions drgn/helpers/linux/net.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
"sk_fullsock",
"sk_nulls_for_each",
"skb_shinfo",
"skb_headlen",
"skb_headroom",
"skb_is_nonlinear",
"skb_tailroom",
"skb_availroom",
"skb_dump",
)


Expand Down Expand Up @@ -260,3 +266,88 @@ def skb_shinfo(skb: Object) -> Object:
return cast("struct skb_shared_info *", skb.head + skb.end)
else:
return cast("struct skb_shared_info *", skb.end)


def skb_headlen(skb: Object) -> Object:
return skb.len - skb.data_len


def skb_headroom(skb: Object) -> Object:
return skb.data - skb.head
Copy link
Owner

Choose a reason for hiding this comment

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

In the kernel, skb_headroom() returns unsigned int, but this returns ptrdiff_t. If we want to be extra accurate, we should cast this here:

Suggested change
return skb.data - skb.head
return cast("unsigned int", skb.data - skb.head)



def skb_is_nonlinear(skb: Object) -> Object:
return skb.data_len
Comment on lines +279 to +280
Copy link
Owner

Choose a reason for hiding this comment

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

I think it would make more sense for this one to return bool:

Suggested change
def skb_is_nonlinear(skb: Object) -> Object:
return skb.data_len
def skb_is_nonlinear(skb: Object) -> bool:
return bool(skb.data_len)



def skb_tailroom(skb: Object) -> IntegerLike:
if skb_is_nonlinear(skb):
return 0
return skb.end - skb.tail
Comment on lines +283 to +286
Copy link
Owner

Choose a reason for hiding this comment

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

Similarly, this one is int in the kernel, so it could be:

Suggested change
def skb_tailroom(skb: Object) -> IntegerLike:
if skb_is_nonlinear(skb):
return 0
return skb.end - skb.tail
def skb_tailroom(skb: Object) -> Object:
if skb_is_nonlinear(skb):
return Object(prog, "int", 0)
return cast("int", skb.end - skb.tail)

There doesn't seem to be much logic in how the return types were picked in the kernel, but we might as well copy those choices for the rest, too.



def skb_availroom(skb: Object) -> IntegerLike:
if skb_is_nonlinear(skb):
return 0

return skb.end - skb.tail - skb.reserved_tailroom


def skb_network_header_len(skb: Object) -> Object:
return skb.transport_header - skb.network_header


def skb_mac_header_len(skb: Object) -> Object:
return skb.network_header - skb.mac_header


def skb_mac_header_was_set(skb: Object) -> bool:
return skb.mac_header != 65535


def skb_transport_header_was_set(skb: Object) -> bool:
return skb.transport_header != 65535


def skb_dump(skb: Object) -> None:
headroom = skb_headroom(skb)
tailroom = skb_tailroom(skb)
sh = skb_shinfo(skb)

has_mac = skb_mac_header_was_set(skb)
has_trans = skb_transport_header_was_set(skb)

print(
"skb len=%u headroom=%u headlen=%u tailroom=%u\n"
"mac=(%d,%d) net=(%d,%d) trans=%d\n"
"shinfo(txflags=%u nr_frags=%u gso(size=%hu type=%u segs=%hu))\n"
"csum(0x%x ip_summed=%u complete_sw=%u valid=%u level=%u)\n"
"hash(0x%x sw=%u l4=%u) proto=0x%04x pkttype=%u iif=%d\n"
% (
Copy link
Owner

Choose a reason for hiding this comment

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

I'd prefer an f-string or at least str.format() over % formatting.

int(skb.len),
int(headroom),
int(skb_headlen(skb)),
int(tailroom),
int(skb.mac_header) if has_mac else -1,
int(skb_mac_header_len(skb)) if has_mac else -1,
int(skb.network_header),
int(skb_network_header_len(skb)) if has_trans else -1,
int(skb.transport_header) if has_trans else -1,
int(sh.tx_flags),
int(sh.nr_frags),
int(sh.gso_size),
int(sh.gso_type),
int(sh.gso_segs),
int(skb.csum),
int(skb.ip_summed),
int(skb.csum_complete_sw),
int(skb.csum_valid),
int(skb.csum_level),
int(skb.hash),
int(skb.sw_hash),
int(skb.l4_hash),
int(skb.protocol),
int(skb.pkt_type),
int(skb.skb_iif),
)
)