Hạt nhân Linux không truyền qua các gói UDP đa hướng


35

Gần đây tôi đã thiết lập Ubuntu Server 10.04 mới và nhận thấy máy chủ UDP của tôi không còn có thể thấy bất kỳ dữ liệu phát đa hướng nào được gửi đến giao diện, ngay cả sau khi tham gia nhóm phát đa hướng. Tôi đã có cùng một thiết lập trên hai máy Ubuntu 8.04.4 LTS khác và không có vấn đề gì khi nhận dữ liệu sau khi tham gia cùng một nhóm phát đa hướng.

Thẻ ethernet là Broadcom netXtreme II BCM5709 và trình điều khiển được sử dụng là:

b $ ethtool -i eth1
driver: bnx2
version: 2.0.2
firmware-version: 5.0.11 NCSI 2.0.5
bus-info: 0000:01:00.1

Tôi đang sử dụng smcroute để quản lý đăng ký phát đa hướng của mình.

b$ smcroute -d
b$ smcroute -j eth1 233.37.54.71

Sau khi tham gia nhóm ip maddr cho thấy đăng ký mới được thêm vào.

b$ ip maddr

    1:  lo
        inet  224.0.0.1
        inet6 ff02::1
    2:  eth0
        link  33:33:ff:40:c6:ad
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        inet  224.0.0.1
        inet6 ff02::1:ff40:c6ad
        inet6 ff02::1
    3:  eth1
        link  01:00:5e:25:36:47
        link  01:00:5e:25:36:3e
        link  01:00:5e:25:36:3d
        link  33:33:ff:40:c6:af
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        inet  233.37.54.71 <------- McastGroup.
        inet  224.0.0.1
        inet6 ff02::1:ff40:c6af
        inet6 ff02::1

Cho đến nay rất tốt, tôi có thể thấy rằng tôi đang nhận dữ liệu cho nhóm phát đa hướng này.

b$ sudo tcpdump -i eth1 -s 65534 host 233.37.54.71
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65534 bytes
09:30:09.924337 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:09.947547 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:10.108378 IP 192.164.1.120.58866 > 233.37.54.71.15574: UDP, length 268
09:30:10.196841 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
...

Tôi cũng có thể xác nhận rằng giao diện đang nhận các gói mcast.

b $ ethtool -S eth1 | grep mcast_pack
rx_mcast_packets: 103998
tx_mcast_packets: 33

Bây giờ đây là vấn đề. Khi tôi cố gắng nắm bắt lưu lượng truy cập bằng máy chủ UDP ruby ​​đơn giản, tôi nhận được dữ liệu bằng không! Đây là một máy chủ đơn giản đọc dữ liệu gửi trên cổng 15572 và in hai ký tự đầu tiên. Điều này hoạt động trên hai Máy chủ Ubuntu 8.04.4, nhưng không phải máy chủ 10.04.

require 'socket'
s = UDPSocket.new
s.bind("", 15572)
5.times do
  text, sender = s.recvfrom(2)
  puts text
end

Nếu tôi gửi một gói UDP được chế tạo bằng ruby ​​đến localhost, máy chủ sẽ nhận được nó và in ra hai ký tự đầu tiên. Vì vậy, tôi biết rằng máy chủ ở trên đang hoạt động chính xác.

irb(main):001:0> require 'socket'
=> true
irb(main):002:0> s = UDPSocket.new
=> #<UDPSocket:0x7f3ccd6615f0>
irb(main):003:0> s.send("I2 XXX", 0, 'localhost', 15572)

Khi tôi kiểm tra số liệu thống kê giao thức, tôi thấy rằng InMcastPkts không tăng. Trong khi trên các máy chủ 8.04 khác, trên cùng một mạng, đã nhận được vài nghìn gói trong 10 giây.

b $ netstat -sgu ; sleep 10 ; netstat -sgu
IcmpMsg:
    InType3: 11
    OutType3: 11
Udp:
    446 packets received
    4 packets to unknown port received.
    0 packet receive errors
    461 packets sent
UdpLite:
IpExt:
    InMcastPkts: 4654 <--------- Same as below
    OutMcastPkts: 3426
    InBcastPkts: 9854
    InOctets: -1691733021
    OutOctets: 51187936
    InMcastOctets: 145207
    OutMcastOctets: 109680
    InBcastOctets: 1246341
IcmpMsg:
    InType3: 11
    OutType3: 11
Udp:
    446 packets received
    4 packets to unknown port received.
    0 packet receive errors
    461 packets sent
UdpLite:
IpExt:
    InMcastPkts: 4656  <-------------- Same as above
    OutMcastPkts: 3427
    InBcastPkts: 9854
    InOctets: -1690886265
    OutOctets: 51188788
    InMcastOctets: 145267
    OutMcastOctets: 109712
    InBcastOctets: 1246341

Nếu tôi cố buộc giao diện vào chế độ lăng nhăng thì không có gì thay đổi.

Lúc này tôi bị kẹt. Tôi đã xác nhận cấu hình kernel đã kích hoạt phát đa hướng. Có lẽ có các tùy chọn cấu hình khác tôi nên kiểm tra?

b $ grep CONFIG_IP_MULTICAST /boot/config-2.6.32-23-server
CONFIG_IP_MULTICAST=y

Bất kỳ suy nghĩ về nơi để đi từ đây?


Đi hình. Tôi đi vào một câu hỏi mới, thuật toán liên quan vui vẻ cho tôi thấy câu hỏi này tồn tại, nhưng nó không có câu trả lời có ý nghĩa. Boo :(.
VxJasonxV

Tôi không chắc chính xác là tôi sẽ trao giải thưởng như thế nào. Một đồng nghiệp đã tìm ra vấn đề và tôi đã hiểu tại sao nó lại xảy ra như thế nào. Tôi rất sẵn lòng để đề xuất giải trí cho cách thưởng tiền thưởng.
VxJasonxV

bạn vẫn ở đây chứ? Tôi có một số câu hỏi cho bạn.
VxJasonxV

Tôi cũng gặp vẫn đề này. Bạn ơi, bạn có giải quyết được không?

Đối với những người khác gặp vấn đề này - hãy đọc tất cả các câu trả lời cho câu hỏi này, vì có 2-3 cài đặt O / S cần được sửa. Chúng tôi giải quyết vấn đề này bằng cách thay đổi rp_filter/proc/sys/net/ipv4/icmp_echo_ignore_broadcastsvà sau đó nó bắt đầu làm việc.
Sam Goldberg

Câu trả lời:


35

Trong trường hợp của chúng tôi, vấn đề của chúng tôi đã được giải quyết bằng các tham số sysctl, một khác với Maciej.

Xin lưu ý rằng tôi không nói cho OP (buecking), tôi đã đến bài đăng này do vấn đề liên quan đến chi tiết cơ bản (không có lưu lượng truy cập phát đa hướng trong vùng người dùng).

Chúng tôi có một ứng dụng đọc dữ liệu được gửi đến bốn địa chỉ multicast và một cổng duy nhất cho mỗi địa chỉ multicast, từ một thiết bị (thường) được kết nối trực tiếp với một giao diện trên máy chủ nhận.

Chúng tôi đã cố gắng triển khai phần mềm này trên một trang web của khách hàng khi nó thất bại một cách bí ẩn mà không rõ lý do. Nỗ lực gỡ lỗi phần mềm này dẫn đến việc kiểm tra mọi cuộc gọi hệ thống, cuối cùng tất cả đều nói với chúng tôi điều tương tự:

Phần mềm của chúng tôi yêu cầu dữ liệu và HĐH không bao giờ cung cấp bất kỳ.

Bộ đếm gói phát đa hướng tăng lên, tcpdump cho thấy lưu lượng truy cập đến hộp / giao diện cụ thể, nhưng chúng tôi không thể làm gì với nó. SELinux đã bị vô hiệu hóa, iptables đang chạy nhưng không có quy tắc nào trong bất kỳ bảng nào.

Bối rối, chúng tôi đã.

Khi ngẫu nhiên chọc vào, chúng tôi bắt đầu suy nghĩ về các tham số kernel mà sysctl xử lý, nhưng không có tính năng tài liệu nào có liên quan đặc biệt hoặc nếu chúng phải làm với lưu lượng phát đa hướng, chúng đã được bật. Ồ, và ifconfig đã liệt kê "MULTICAST" trong dòng tính năng (lên, phát, chạy, phát đa hướng). Vì tò mò mà chúng tôi nhìn vào /etc/sysctl.conf. 'lo và kìa, hình ảnh cơ sở của khách hàng này có thêm một vài dòng thêm vào nó ở phía dưới.

Trong trường hợp của chúng tôi, khách hàng đã thiết lập net.ipv4.all.rp_filter = 1. rp_filter là bộ lọc Đường dẫn tuyến, mà (theo tôi hiểu), từ chối tất cả lưu lượng truy cập không thể đến được hộp này. Mạng con nhảy lên, suy nghĩ rằng IP nguồn đang bị giả mạo.

Chà, máy chủ này nằm trên mạng con 192.168.1 / 24 và địa chỉ IP nguồn của thiết bị cho lưu lượng phát đa hướng nằm ở đâu đó trong mạng 10. *. Do đó, bộ lọc đã ngăn máy chủ thực hiện bất kỳ điều gì có ý nghĩa với lưu lượng.

Một vài điều chỉnh được khách hàng chấp thuận; net.ipv4.eth0.rp_filter = 1net.ipv4.eth1.rp_filter = 0chúng tôi đã chạy rất vui vẻ


2
Điều này đã làm việc! Các rp_filter10 giao diện mạng Gb của chúng tôi được bán phá giá tất cả các gói tin multicast UDP của chúng tôi. Tắt bộ lọc để mọi thứ chảy qua.
chrisaycock

Chúng tôi đã gặp sự cố khi thiết lập phát trực tuyến qua AMT multicast qua thiết bị điều chỉnh trên máy thu Ubuntu và chúng tôi có thể thấy các gói được gửi đến thiết bị qua tcpdump, nhưng ứng dụng không muốn truyền phát. Bài đăng này đã cứu chúng tôi!
kỹ sư phần mềm

2
Chạy trên Ubuntu 14.04, điều này chỉ hoạt động với tôi sau khi tôi cũng thiết lập net.ipv4.all.rp_filter = 0. Cụ thể, với dữ liệu phát đa hướng đến trên eth2, tôi phải đặt cả hai net.ipv4.eth2.rp_filter = 0net.ipv4.all.rp_filter = 0.
T-Hawk

4

TL / DR Cũng đảm bảo rằng multicast của bạn không đến từ vlan. tcpdump -esẽ giúp xác định nếu họ làm.

Nói một cách công bằng, ai đó nên xây dựng một trang với một danh sách kiểm tra những thứ có thể ngăn chặn phát đa hướng đến vùng người dùng. Tôi đã vật lộn với điều đó trong một vài ngày, và tự nhiên tôi không thể tìm thấy gì trên web.

Không chỉ tôi có thể thấy các gói trong tcpdump, tôi thực sự có thể nhận các gói phát đa hướng khác, đối với các nhà sản xuất khác, chỉ trên một giao diện khác. Lệnh tôi đã kết thúc bằng cách sử dụng để kiểm tra xem tôi có thể nhận phát đa hướng hay không là:

$ GRP=224.x.x.x # set me to the group
$ PORT=yyyy # set me to the receiving port
$ IFACE=mmmm # set me to the name or IP address of the interface
$ strace -f socat -  UDP4-DATAGRAM:$GRP:$PORT,ip-add-membership=$GRP:$IFACE,bind=0.0.0.0:$PORT,multicast-loop=0

Lý do straceở đây là tôi thực sự không thể socatin các gói ra thiết bị xuất chuẩn, nhưng trong straceđầu ra, bạn có thể thấy rõ nếu socatnhận được dữ liệu thực tế từ ổ cắm bị ràng buộc (nó sẽ bị tắt tiếng sau một vài selectcuộc gọi ban đầu )

  • rp_filtersysctl - không áp dụng, các hệ thống nằm trên cùng một mạng IP (Tôi đặt chúng hoàn 0toàn giống nhau, dường như đó 1là cài đặt mặc định bây giờ, ít nhất là cho Ubuntu).
  • tường lửa / vv - hệ thống nhận không có tường lửa (Tôi không nghĩ các gói sẽ hiển thị trong tcpdump nếu chúng được tường lửa, nhưng tôi đoán là có thể nếu tường lửa buồn cười)
  • Định tuyến IP / Multicast và nhiều giao diện - Tôi rõ ràng đã tham gia nhóm trên giao diện chính xác
  • Phần cứng mạng lập dị - đây là phương án cuối cùng của tôi, nhưng việc thay đổi một số máy tính xách tay thành Intel NUC không giúp được gì. Đây là về nơi tôi bắt đầu nhai khuỷu tay của mình và liên tục đăng bài này lên SE.
  • Vấn đề trong trường hợp của tôi là việc sử dụng Vlan bởi phần cứng chuyên dụng đang sản xuất các gói phát đa hướng đó. Để xem đây có phải là vấn đề của bạn không, hãy đảm bảo bao gồm -ecờ tcpdumpvà kiểm tra các thẻ vlan. Sẽ được yêu cầu cấu hình một giao diện vào đúng vlan trước khi userland có thể nhận được các gói đó. Sự cho đi đối với tôi thực sự là các nhà sản xuất phát đa hướng sẽ không ping, nhưng thậm chí sẽ không vào được bộ đệm ARP, mặc dù tôi có thể thấy rõ các câu trả lời của ARP.

Để làm cho nó chạy với Vlan , liên kết này có thể hữu ích để định cấu hình định tuyến phát đa hướng. (Đáng buồn là tôi chưa quen với điều này nên Danh tiếng không cho phép tôi thêm câu trả lời. Do đó, chỉnh sửa này.)

Đây là những gì tôi đã làm (sử dụng sudo nếu cần):

ip link add link eth0 name eth0_100 type vlan id 100
ip addr add 192.168.100.2/24 brd 192.168.100.255 dev eth0_100
ip link set dev eth0_100 up
ip maddr add 01:00:5e:01:01:01 dev eth0_100
route -n add -net 224.0.0.0 netmask 240.0.0.0 dev eth0_100

Bằng cách này, một giao diện bổ sung nếu được tạo cho lưu lượng vlan với vlan id 100. IP vlan có thể không cần thiết. Sau đó, một địa chỉ multicast được cấu hình cho giao diện mới (01: 00: 5e: 01: 01: 01 là địa chỉ lớp liên kết cho 239.1.1.1) và tất cả lưu lượng truy cập phát đa hướng đến được liên kết với eth0_100. Tôi cũng đã làm tất cả các bước có thể trong các câu trả lời ở trên (kiểm tra iptables, rp_filter, v.v.).


@Gero: Thêm tuyến phát đa hướng sẽ thiết lập phát đa hướng đi , không phát đa hướng đến. Bạn không nên liên kết trực tiếp các địa chỉ IP multicast với các giao diện, trừ khi bạn đang làm điều gì đó thú vị, đó thường là công việc của ứng dụng.
Pawel Veselov

2

Bạn có thể muốn thử và xem các cài đặt này:

Proc

echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

sysctl.conf

sed -i -e 's|^net.ipv4.icmp_echo_ignore_broadcasts =.*|net.ipv4.icmp_echo_ignore_broadcasts = 0|g' /etc/sysctl.conf

Những cái này đã được sử dụng để cho phép phát đa hướng trong RHEL.

Bạn có thể muốn đảm bảo rằng tường lửa của bạn cho phép lưu lượng truy cập đột biến; một lần nữa với RHEL tôi đã kích hoạt như sau:

# allow anything in on multicast addresses
-A INPUT -s 224.0.0.0/4 -j ACCEPT
-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT
# needed for multicast ping responses
-A INPUT -p icmp --icmp-type 0 -j ACCEPT

Tùy chọn "quảng bá" cũng áp dụng cho "phát đa hướng"?
Raedwald

0

Bạn đang sử dụng một công tắc được quản lý? Một số có các tùy chọn để ngăn chặn 'cơn bão phát sóng' hoặc các sự cố phát đa hướng khác, điều đó sẽ khiến chúng ngăn chặn một số loại gói nhất định. Tôi khuyên bạn nên xem tài liệu chuyển đổi của bạn.


0
s.bind("", 15572)

Chắc chắn về ""? Tại sao không sử dụng địa chỉ IP multicast để liên kết?


địa chỉ máy chủ trống thường có nghĩa là "tất cả các giao diện".
VxJasonxV
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.