Ядро Linux не может принимать многоадресную рассылку

Я собрал ядро ​​Linux с CONFIG_IP_MULTICAST=y, однако многоадресный пакет UDP не был получен в этом ядре, в то время как одноадресная рассылка UDP работает хорошо.

ethtool -S eth0 | grep multicast                         
txmulticastframes_g: 0                   
txmulticastframes_gb: 0             
rxmulticastframes_g: 0

Любые подсказки, как я могу решить эту проблему?

Спасибо. Форрест Джи

================================================== =============================== Дополнительно:
tcpdump может получить пакет

root@JHI # ./tcpdump port 3702
device eth0 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
-7:-48:-19.4151 IP 192.168.42.212.3702 > 239.255.255.250.3702: UDP, length 787
-7:-48:-19.4661 IP 192.168.42.212.3702 > 239.255.255.250.3702: UDP, length 803
^C
2 packets captured
2 padevice eth0 left promiscuous mode
ckets received by filter
0 packets dropped by kernel

Я пишу эту функцию обнаружения устройств WS с помощью gSOAP. Он работает на машине X86. При работе на устройстве ARM он может отправлять пакеты igmp, но ничего не получает.

void wsdd()  
{      
    struct soap *soap_udp;   
    struct ip_mreq mreq;   

    soap_udp=soap_new();  
    soap_init1(soap_udp, SOAP_IO_UDP|SOAP_IO_FLUSH);  

    if (!soap_valid_socket(soap_bind(soap_udp, NULL, 3702, 100)))  
    {      
        soap_print_fault(soap_udp, stderr);  
    }  

    mreq.imr_multiaddr.s_addr = inet_addr("239.255.255.250");  
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);  

    if(setsockopt(soap_ud->master,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq))==-1)     {  
        perror("membership error\n");  
    }

    int loop = 1;  
    int sock_opt = 1;
    if ((setsockopt(soap_udp->master, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_opt,  
                    sizeof (sock_opt))) == -1) {  
        printf("setsockopt\n");  
    }  
    if ((setsockopt(soap_udp->master, IPPROTO_IP, IP_MULTICAST_LOOP,  
                       &loop, sizeof (loop))) == -1) {  
        printf("setsockopt\n");  
    }

    while(1){  
        soap_accept(soap_udp);
        soap_serve(soap_udp);   
        soap_end(soap_udp); 
    }  
} 

Затем я пробовал эти вещи, но все еще не работал

route add -net 224.0.0.0 netmask 240.0.0.0 eth0
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

person ForrestG    schedule 22.05.2013    source источник
comment
Пожалуйста, включите код, который вы написали для получения многоадресной рассылки UDP (программа должна использовать параметр сокета IP_ADD_MEMBERSHIP для присоединения к группе многоадресной рассылки).   -  person caf    schedule 22.05.2013
comment
Вы пытаетесь отправить многоадресную рассылку и получить ее на одном и том же ящике?   -  person Nikolai Fetissov    schedule 24.05.2013
comment
Нет, я пытаюсь прослушать внешнее многоадресное сообщение и ответить на одноадресное сообщение.   -  person ForrestG    schedule 27.05.2013


Ответы (1)


Проблема решается заменой..

ifconfig eth0 promisc

Кто-нибудь может объяснить принцип?

person ForrestG    schedule 27.05.2013
comment
Я предполагаю, что способность перехватывать многоадресную рассылку вашей сетевой картой в значительной степени зависит от ее драйвера. Поскольку многоадресные пакеты IPv4 указываются для использования определенного адреса назначения ссылки, полученного из целевой группы многоадресной рассылки, при транспортировке по Ethernet, вы должны каким-то образом заставить свою сетевую карту принимать кадры Ethernet с этими адресами. Современные сетевые карты AFAIK могут иметь до 4 или 8 разных MAC-адресов, для которых они будут получать, но ваш драйвер должен иметь возможность настроить их для этого. В противном случае вы можете использовать неразборчивый режим, который в основном означает, что сетевая карта не будет фильтровать входящие кадры на основе MAC-адреса. Ошибка драйвера. - person Jan Smrčina; 03.02.2016