• debug ipv6 不通 ngbe驱动丢包


    目前遇到问题如下:IPv6 http以及ping 不通主机 同一个网段!

    为了找出原因:想用systemtap 但是编译对应环境的systemtap 失败,x86正常 但是 arm-linux 失败,没办法只能选择使用kprobe了

     排查的问题的时候,使用tcpdump 抓包能抓到包, 然后就通了!!

    使用kprobe debug 了一下 netif_receive_skb ; 发现没有收到报文!!

    #define NIP6(addr) 
        ntohs((addr).s6_addr16[0]), 
        ntohs((addr).s6_addr16[1]), 
        ntohs((addr).s6_addr16[2]), 
        ntohs((addr).s6_addr16[3]), 
        ntohs((addr).s6_addr16[4]), 
        ntohs((addr).s6_addr16[5]), 
        ntohs((addr).s6_addr16[6]), 
        ntohs((addr).s6_addr16[7])
        
    #define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
        
    static void print_skb_ipv6(const struct sk_buff* skb)
    {
        struct ipv6hdr* ip6h;
        struct tcphdr* th;
        struct in6_addr ip6_sip, ip6_dip;
        int    sport, dport;
    
        
        
        ip6h = ipv6_hdr(skb);
        
        ip6_sip = ip6h->saddr;
        ip6_dip = ip6h->daddr;
        
        if (ip6h->nexthdr != NEXTHDR_TCP && ip6h->nexthdr != NEXTHDR_ICMP ) {
            return;
        }
        if (ip6h->nexthdr == NEXTHDR_ICMP) {
            printk(" Source: "NIP6_FMT"  Dest: " NIP6_FMT"  icmp ------>
    ",
                    NIP6(ip6_sip), NIP6(ip6_dip));
            return;
        }
        
        
        //skb->transport_header = skb->network_header + sizeof(*ip6h);
        th = tcp_hdr(skb);
        sport = ntohs(th->source);
        dport = ntohs(th->dest);
        printk("tcp  Source: "NIP6_FMT" sport:%d --->Dest:  "NIP6_FMT" dport:%d    --->n", NIP6(ip6_sip), sport, NIP6(ip6_dip), dport);
    
                
        return;    
    }
    
    
    static int ipv6_rcv_hook(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
    {
        
        print_skb_ipv6(skb);
    
        jprobe_return();
        return 0;
    }
    
    static struct jprobe ipv6_recv_probe;
    
    static int probe_netif_receive_skb_fun(struct sk_buff *skb)
    {
        __be16 type;
        type = skb->protocol;
    
        if (type == htons(ETH_P_IPV6)) {
            struct ipv6hdr *hdr;
            
            hdr = (struct ipv6hdr *)(skb->data);
            if (hdr->nexthdr == NEXTHDR_ICMP ) {
                printk(" dev source: "NIP6_FMT"  Dest: " NIP6_FMT"  dev_netif_receive icmp------>
    ",
                    NIP6(hdr->saddr), NIP6(hdr->daddr));
            }else if(hdr->nexthdr == NEXTHDR_TCP) {
                printk(" dev source: "NIP6_FMT"  Dest: " NIP6_FMT"  dev_netif_receive tcp------>
    ",
                    NIP6(hdr->saddr), NIP6(hdr->daddr));
                
            }else {
                printk("dev source: "NIP6_FMT"  Dest: " NIP6_FMT"  dev_netif_receive ipporttype:0x%x---0x%x--->
    ",
                       NIP6(hdr->saddr), NIP6(hdr->daddr), hdr->nexthdr , ntohs(hdr->nexthdr));
                
            }
        }
        
        jprobe_return();
        return 0;
        
    }
    
    static struct jprobe  probe_netif_receive_skb;
    
    int kp_init(void)
    {
        int    retval;
    
        ipv6_recv_probe.kp.addr = (kprobe_opcode_t*)kallsyms_lookup_name("ipv6_rcv");
        ipv6_recv_probe.entry = (kprobe_opcode_t*)ipv6_rcv_hook;
        retval = register_jprobe(&ipv6_recv_probe);
        pr_notice("init register_jprobe %d
    ", retval);
    
    
        probe_netif_receive_skb.kp.addr = (kprobe_opcode_t*)kallsyms_lookup_name("netif_receive_skb");
        probe_netif_receive_skb.entry = (kprobe_opcode_t*)probe_netif_receive_skb_fun;
        retval = register_jprobe(&probe_netif_receive_skb);
        pr_notice("init probe_netif_receive_skb register_jprobe %d
    ", retval);
    
        return 0;
    }
    
    void kp_exit(void)
    {
        unregister_jprobe(&ipv6_recv_probe);
        unregister_jprobe(&probe_netif_receive_skb);
        pr_notice("module removed
     ");
    }

    所以此时认为是 驱动将报文丢弃! 由于tcpdump会将驱动dev的属性设置为 

        hw->addr_ctrl.user_set_promisc = false;
        if (netdev->flags & IFF_PROMISC) {
            hw->addr_ctrl.user_set_promisc = true;
            fctrl |= (NGBE_PSR_CTL_UPE | NGBE_PSR_CTL_MPE);
            /* pf don't want packets routing to vf, so clear UPE */
            vmolr |= NGBE_PSR_VM_L2CTL_MPE;
            vlnctrl &= ~NGBE_PSR_VLAN_CTL_VFE;
        }

      在 set_rx_mode 属性中可以看到 #define NGBE_PSR_VM_L2CTL_MPE          0x00001000U /* multicast promiscuous */

    设置 抓取组播报文!! 由于ipv6 中的邻居协议 探测 ip 对应的mac 时, 其nd 邻居协议发送探测报文对应的使用 组播mac ,所以可能驱动不设置的时候 会将 报文丢弃!!

    /* This is useful for sniffing bad packets. */
        if (netdev->features & NETIF_F_RXALL) {
            vmolr |= (NGBE_PSR_VM_L2CTL_UPE | NGBE_PSR_VM_L2CTL_MPE);
            vlnctrl &= ~NGBE_PSR_VLAN_CTL_VFE;
            /* receive bad packets */
            wr32m(hw, NGBE_RSEC_CTL,
                NGBE_RSEC_CTL_SAVE_MAC_ERR,
                NGBE_RSEC_CTL_SAVE_MAC_ERR);

    驱动中还有 rxall 标志!! 所以设置为rx_all 在测试其是否正常!

    目前看 设置此标志后!! 能够解决问题

    后续在 分析这里面使用到的 hook_napi 技术

     

    http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!! 但行好事 莫问前程 --身高体重180的胖子
  • 相关阅读:
    AJAX
    前端上传文件 后端PHP获取文件
    PHP基础语法
    JS错误记录
    JS学习笔记
    python利用xlrd读取excel文件始终报错原因
    安装xlwt和xlrd
    编程菜鸟的日记-Linux无处不在
    编程菜鸟的日记-《软件测试》Ron Patton著-读书笔记
    编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第6章编程练习9
  • 原文地址:https://www.cnblogs.com/codestack/p/14851280.html
Copyright © 2020-2023  润新知