Last active
January 7, 2022 20:38
-
-
Save christarazi/4bb48eb623a03f25026be21856ea10fb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/skbuff.h> | |
#include <net/flow.h> | |
#include <net/xfrm.h> | |
/* | |
* This script was used to debug https://github.com/cilium/cilium/issues/15826 | |
* and create https://github.com/cilium/cilium/pull/16057. | |
* | |
* The script will attach to functions in the XFRM subsystem around XFRM | |
* policy lookup and evaluation. The probes are defined in the order of their | |
* execution when a packet arrives into the kernel. | |
* | |
* Packets are identified across the different probes by their mark. | |
*/ | |
/* Optional */ | |
/* kprobe:skb_scrub_packet */ | |
/* { */ | |
/* #<{(| void skb_scrub_packet(struct sk_buff *skb, bool xnet) |)}># */ | |
/* */ | |
/* $skb = (struct sk_buff *) arg0; */ | |
/* $xnet = arg1; */ | |
/* */ | |
/* printf("scrub(skb->mark:0x%x, xnet:%d)\n", $skb->mark, $xnet); */ | |
/* } */ | |
kprobe:secpath_set | |
{ | |
/* struct sec_path *secpath_set(struct sk_buff *skb) */ | |
$skb = (struct sk_buff *) arg0; | |
printf("secpath_set(skb->mark:0x%x) ", $skb->mark); | |
} | |
kretprobe:secpath_set | |
{ | |
printf("=> %d\n", retval); | |
} | |
kprobe:__xfrm_policy_check | |
{ | |
/* int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |
* unsigned short family) | |
*/ | |
$sock = arg0; | |
$dir = arg1 & XFRM_POLICY_MASK; | |
$skb = (struct sk_buff *) arg2; | |
$family = arg3; | |
/* static inline bool skb_ext_exist(const struct sk_buff *skb, enum skb_ext_id id) | |
* { | |
* return skb->active_extensions & (1 << id); | |
* } | |
*/ | |
$id = SKB_EXT_SEC_PATH; | |
if (($skb->active_extensions & (1 << $id)) != 0) { | |
$ext = "skb active extensions"; | |
/* static inline void *skb_ext_find(const struct sk_buff *skb, enum skb_ext_id id) | |
* { | |
* if (skb_ext_exist(skb, id)) { | |
* struct skb_ext *ext = skb->extensions; | |
* | |
* return (void *)ext + (ext->offset[id] << 3); | |
* } | |
* | |
* return NULL; | |
* } | |
*/ | |
$sp = (struct skb_ext *) $skb->extensions; | |
/* bpftrace don't allow dynamic array access, so the `1` is | |
*`SKB_EXT_SEC_PATH`, aka `$id`. | |
* | |
* We also must cast to a integral pointer type and dereference | |
* in order to do the arithmetic, otherwise bpftrace will complain. | |
*/ | |
$sp = (struct skb_ext *) ((*(uint8 *) $sp) + ($sp->offset[1] << 3)); | |
} else { | |
$ext = "no extensions"; | |
} | |
printf("check(X, dir:%d, skb->mark:0x%x (%s [sp:%d]), family:%hu)\n", | |
$dir, $skb->mark, $ext, $sp, $family); | |
} | |
kretprobe:__xfrm_policy_check | |
{ | |
printf("check() => %d\n", retval); | |
} | |
kprobe:xfrm_policy_lookup_bytype | |
{ | |
/* static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type, | |
* const struct flowi *fl, | |
* u16 family, u8 dir, | |
* u32 if_id) | |
*/ | |
$type = arg1; | |
$fl = (struct flowi *) arg2; | |
$family = arg3; | |
$dir = arg4; | |
$if_id = arg5; | |
if ($type == 0) { | |
printf(" lookup(X, flmark:0x%x, family:%u, dir:%u, if_id:%u)\n", | |
$fl->flowi_mark, $family, $dir, $if_id); | |
} | |
} | |
kretprobe:xfrm_policy_lookup_bytype | |
{ | |
printf(" lookup() => %d\n", retval); | |
} | |
kprobe:xfrm_policy_match | |
{ | |
/* static int xfrm_policy_match(const struct xfrm_policy *pol, | |
* const struct flowi *fl, | |
* u8 type, u16 family, int dir, u32 if_id) | |
*/ | |
$pol = (struct xfrm_policy *) arg0; | |
$fl = (struct flowi *) arg1; | |
$type = arg2; | |
$family = arg3; | |
$dir = arg4; | |
$if_id = arg5; | |
if ($type == 0) { | |
/* if (pol->family != family || | |
* pol->if_id != if_id || | |
* (fl->flowi_mark & pol->mark.m) != pol->mark.v || | |
* pol->type != type) | |
* return ret; | |
*/ | |
printf(" match(X, type:%hu, X, family:%u, dir:%u, if_id:%u)\n", | |
$type, $family, $dir, $if_id); | |
printf(" pol->family: %u\n", $pol->family); | |
printf(" pol->if_id: %u\n", $pol->if_id); | |
/* (fl->flowi_mark & pol->mark.m) != pol->mark.v || */ | |
printf(" flowi_mark:0x%x & pol->mark.m:0x%x != pol->mark.v:0x%x\n", | |
$fl->flowi_mark, $pol->mark.m, $pol->mark.v); | |
} | |
} | |
kretprobe:xfrm_policy_match | |
{ | |
printf(" match() => %d\n", retval); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/skbuff.h> | |
#include <uapi/linux/ip.h> | |
#include <linux/byteorder/generic.h> | |
kprobe:__xfrm_policy_check | |
{ | |
$dir = arg1; | |
$skb = (struct sk_buff *) arg2; | |
$family = arg3; | |
$ip_header = (struct iphdr *) ($skb->head + $skb->network_header); | |
printf("check(X, dir:%d, (%u %u) mark:0x%x, family:%d)\n", | |
$dir, $ip_header->saddr, $ip_header->daddr, $skb->mark, $family); | |
} | |
kretprobe:__xfrm_policy_check | |
{ | |
printf("check() => %d\n", retval); | |
} | |
kprobe:xfrm_policy_lookup | |
{ | |
$fl = (struct flowi *) arg1; | |
$family = arg2; | |
$dir = arg3; | |
$if_id = arg4; | |
printf(" lookup(X, X, flmark:0x%x, family:%u, dir:%u, if_id:%u) ", | |
$fl->flowi_mark, $family, $dir, $if_id); | |
} | |
kretprobe:xfrm_policy_lookup | |
{ | |
printf("=> %d\n", retval); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment