zoukankan      html  css  js  c++  java
  • 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的胖子
  • 相关阅读:
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第一部分)——IDiscoveryService
    MS CRM 2011的自定义和开发(7)——视图编辑器(第二部分)
    MS CRM 2011 SDK 5.06版本已经发布
    MS CRM 2011的自定义和开发(11)——插件(plugin)开发(一)
    近来遇到的MS CRM 2011方面的几个问题
    MS CRM 2011的自定义与开发(6)——表单编辑器(第二部分)
    Microsoft Dynamics CRM 2011中,Lookup字段的赋值
    MS CRM 2011的自定义和开发(6)——表单编辑器(第三部分)
    Visual Studio 目标框架造成 命名空间“Microsoft”中不存在类型或命名空间名称“Crm”。是否缺少程序集引用中错误的处理
    一步步学习Reporting Services(二) 在报表中使用简单的参数作为查询条件
  • 原文地址:https://www.cnblogs.com/codestack/p/14851280.html
Copyright © 2011-2022 走看看