From: Tang Longjun <[email protected]>

track the IP header information of packets through the kprobe
ip_local_deliver function

Signed-off-by: Tang Longjun <[email protected]>
---
 tools/virtio/virtnet_mon/virtnet_mon.c | 42 +++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/tools/virtio/virtnet_mon/virtnet_mon.c 
b/tools/virtio/virtnet_mon/virtnet_mon.c
index 9c0b5ebc3f03..69b4afcbeb56 100644
--- a/tools/virtio/virtnet_mon/virtnet_mon.c
+++ b/tools/virtio/virtnet_mon/virtnet_mon.c
@@ -440,6 +440,8 @@ enum event_type {
        START_XMIT_POST_EVENT = 2,
        GRO_RECEIVE_SKB_PRE_EVENT = 3,
        GRO_RECEIVE_SKB_POST_EVENT = 4,
+       IP_LOCAL_DELIVER_PRE_EVENT = 5,
+       IP_LOCAL_DELIVER_POST_EVENT = 6,
 };
 
 struct iph_info {
@@ -482,6 +484,7 @@ static char read_buf[READ_SIZE];
 
 static struct kprobe start_xmit_kp;
 static struct kprobe gro_receive_skb_kp;
+static struct kprobe ip_local_deliver_kp;
 
 /* convert pkt_dir to string */
 static const char *pkt_dir_to_str(enum pkt_dir dir)
@@ -522,7 +525,11 @@ static const char *event_type_to_str(enum event_type 
event_type)
        case GRO_RECEIVE_SKB_PRE_EVENT:
                return "GRO_RECEIVE_SKB_PRE_EVENT";
        case GRO_RECEIVE_SKB_POST_EVENT:
-                       return "GRO_RECEIVE_SKB_POST_EVENT";
+               return "GRO_RECEIVE_SKB_POST_EVENT";
+       case IP_LOCAL_DELIVER_PRE_EVENT:
+               return "IP_LOCAL_DELIVER_PRE_EVENT";
+       case IP_LOCAL_DELIVER_POST_EVENT:
+               return "IP_LOCAL_DELIVER_POST_EVENT";
        default:
                return "Unknown";
        }
@@ -757,6 +764,26 @@ static int gro_receive_skb_pre_handler(struct kprobe *p, 
struct pt_regs *regs)
        return 0;
 }
 
+/* Kprobe pre-handler for ip_local_deliver */
+static int ip_local_deliver_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+       struct sk_buff *skb;
+       struct virtnet_mon_pkt_info info;
+
+       /* Get skb parameter (first parameter) */
+       skb = (struct sk_buff *)KP_GET_ARG(regs, 0);
+
+       memset(&info, 0, sizeof(struct virtnet_mon_pkt_info));
+       get_common_info(PKT_DIR_RX, IP_LOCAL_DELIVER_PRE_EVENT, &info);
+       if (get_iph_info(skb, &info.iph_info) != 0)
+               return 0;
+
+       kfifo_in(&virtnet_mon_kfifo, &info, 1);
+       wake_up_interruptible(&virtnet_mon_wq);
+
+       return 0;
+}
+
 // open device
 static int virtnet_mon_open(struct inode *inode, struct file *file)
 {
@@ -904,6 +931,18 @@ static int __init virtnet_mon_init(void)
        }
        pr_info("virtnet_mon: Registered kprobe for gro_receive_skb\n");
 
+       /* Setup kprobe for ip_local_deliver */
+       ip_local_deliver_kp.pre_handler = ip_local_deliver_pre_handler;
+       ip_local_deliver_kp.symbol_name = "ip_local_deliver";
+
+       ret = register_kprobe(&ip_local_deliver_kp);
+       if (ret < 0) {
+               pr_info("virtnet_mon: Failed to register kprobe for 
ip_local_deliver: %d\n", ret);
+               unregister_kprobe(&ip_local_deliver_kp);
+               return ret;
+       }
+       pr_info("virtnet_mon: Registered kprobe for ip_local_deliver\n");
+
        return 0;
 }
 
@@ -916,6 +955,7 @@ static void __exit virtnet_mon_exit(void)
        /* Unregister kprobes */
        unregister_kprobe(&start_xmit_kp);
        unregister_kprobe(&gro_receive_skb_kp);
+       unregister_kprobe(&ip_local_deliver_kp);
        pr_info("virtnet_mon: Unloading module\n");
 }
 
-- 
2.43.0


Reply via email to