-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multicast Support - Work In Progress #1019
base: main
Are you sure you want to change the base?
Conversation
Thanks @evpopov for creating the PR. As discussed we will be actively reviewing the PR and keep you updated on the review status. Please publish the PR, this will help in hastening the review process. |
Hello @evpopov , Thank you, |
/bot run formatting |
I will try rebasing this PR to keep it up to date instead of merging. I know it may be a bit unorthodox, but this way I can clearly see all the changes from start to end that this PR makes. This is still work in progress. Thanks for your patience. |
That's always my strategy so not a problem. Also thank you for the status update :) |
Force-push log: This was not ideal, so I just moved the function in question to Sockets.c where it belongs and rebased to the latest main. |
Hi @evpopov |
/bot run formatting |
1 similar comment
/bot run formatting |
I was lucky enough to be able to work on this for almost the entire week. Check my latest commit description for details, but in summary, this PR now send IGMPv2 and MLD v1 Reports for all registered multicast groups. One of my WiFi access points at work is doing some sort of multicast pruning and is probably running IGMP/MLD snooping but It would never pass multicast messages to my device's solicited-node address. This resulted in my ethernet-connected device being inaccessible over IPv6 from PCs connected to the WiFi part of my office network. The PC's would try to send a neighbor solicitation to my device's solicited-node multicast address, but those messages would never reach the device. Once I got the device to send out MLD Reports, the WiFi AP now knew that my device was interested in receiving it's solicited-node multicast address and my IPv6 connectivity was miraculously fixed. Back to my update.... This is still very much a work in progress, but it is now sort of functional on both IPv4 and IPv6 and multiple interfaces and that is quite a step up from my original code-base. There is a lot of cleanup to be done and functionality to be added. For example, I need to add functionality for parsing MLD Queries that complements the existing IGMP query parser code. p.s. Originally I kept most changes in my added IGMP files, but as this PR gets more and more involved with IPv6 and multiple end-points, I'm starting to move functions and definitions from "my segregated IGMP files" to the regular code base. This makes the PR look more and more far-reaching because it affects a lot of files, but there's not much I can do about it. I'll do my best to squash multiple commits and keep this PR rebased on the latest main. |
/bot run formatting |
This PR now also works with IPv6 sockets. Quick and dirty IPv4/IPv6 receive example:
Here's a small python script to generate traffic received by the code above:
Quick and dirty IPv4 send example:
The code still needs work on how interfaces and sockets interact. The way I understand things with other operating systems and stacks is that in IPv4 we can subscribe to a multicast group on either a specific interface, or on all interfaces and the specific interface is designated by it's IP address. |
\bot run formatting |
I updated the sample code above to reflect the latest changes. The changes are that the code now uses identical socket option names and option values for both IPv4 and IPv6. The latest commit also adds a field to the NetworkBufferDescriptor_t. That field represents the outgoing TTL for packets. The field is added without #ifdef because it is used even with multicasts disabled. The latest commit populates the field in all possible situations except TCP, so that the proper TTL value is used based on the packet that is being sent. This new field is also used for the "Hop Limit" field which is the IPv6 equivalent of TTL Still, don't look too closely into the details of the code. I have to rename the IGMP file to something more generic and I will also be squashing the commits soon. |
/bot run formatting |
source/FreeRTOS_IGMP.c
Outdated
|
||
if( pxNetworkBuffer->xDataLength < sizeof( IGMPPacket_t ) ) | ||
{ | ||
return eReturn; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have single return statement per function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tony-josi-aws Yes, I'm aware of that and it is on my to-do list to go over things like returns, naming, casting, etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can help out on the MISRA violations once the code is stable.
Update:
I still have not implemented the NetworkInterface <-> MulticastGroup relationship. I will get back on this in 1 week. |
2461729
to
6292e9d
Compare
Hi @evpopov I pulled the code from MCast_PR, for this we are working on the driver adsp-sc594 with the ip 100.64.10.5 for this ip we are able to get multicast messages from wireshark |
Hi @tbhavya443,
Hope that helps. |
a70e996
to
9a93d14
Compare
af5b7ae
to
78d699f
Compare
2b08654
to
bddae66
Compare
Since #1065 got merged recently, I have rebased this PR onto main and force-pushed so that all changes are clearly visible in a single commit. |
Hi @evpopov I'd like to use multicast in +tcp(ipv4), and I have rebased your MCast_PR branch onto main. |
@large-cat The PR is not merged yet because unit tests and memory safety proofs(CBMC) needs to be updated/added. We haven't had the chance to do it from our side yet due to other pressing priorities. We would welcome any contribution on that side. Also, If you use this PR for testing the feature, please do share your feedback. Thank you. |
@large-cat, With that being said, my production code uses this PR and I'm happy with how it works, so I think you are relatively safe using it. As @amazonKamath mentioned, Id you end up using this PR or even if you just test it out, please give us your feedback. |
|
@evpopov Thank you guys for all of the work you've done adding Multicast, it's an important part of a project I'm working on. I have to ask: is there any intention to support multiple groups on one socket? Implementing an EtherNet/IP Adapter that can support multiple Scanners seems to demand that functionality, at least given certain local constraints. |
@mpowellADC Thanks for the kind words! I'm very happy that people are finding this branch useful. It sounds like you may be developing an Ethernet/IP master and if that is the case, you could use unicast connections to minimize the load on the network. That will allow your server to use 1 socket to talk to as many slave devices as you have resources for. |
@evpopov Thanks for the reply! Unfortunately this project doesn't have the freedom to choose not to support something as standard as multicast listening on Ethernet/IP. We may wind up having to hack that group list back in. |
Modifies eConsiderFrameForProcessing() to allow all multicast ethernet frames when ipconfigSUPPORT_IP_MULTICAST is enabled and ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is disabled. Adds parsing of IGMP and MLD queries. Sends IGMPv2 and MLDv1 reports on a schedule that is updated based on received IGMP/MLD queries. Sends unsolicited IGMP and MLD reports on network-up events and on add-membership socket option. Adds pxSocket->u.xUDP.xMulticastTTL that can be used for both IPv4 and IPv6 Adds pxSocket->u.xUDP.xMulticastAddress that can be used for both IPv4 and IPv6 Adds pxSocket->u.xUDP.pxMulticastNetIf that specifies the interface on which a sockets wants to receive multicasts. Adds socket option defines to add/drop membership as well as change the transmit TTL of multicasts. Makes all 3 multicast socket options (add/drop/ttl) work with both IPv4 and IPv6 Adds a ucMaximumHops field to NetworkBufferDescriptor_t and assigns it to the proper TTL/HopLimit value based on what packet is being sent. Adds exceptions so that we don't send multicast reports for 224.0.0.1, ff02::1, as well as anything with IPv6 multicast scope of 0 or 1 Adds defines for MLD packets like the Multicast Listener Query and Report. The MLD report defines are different for transmitted and received packets because the stack strips the optional headers from received MLD packets. Generates an MLD report for the solicited-node multicast addresses corresponding to all unicast IPv6 addresses Sends IGMPv2 Leave Group messages whenever the last socket subscribed to a group drops that membership. On network down, stops receiving the MAC address that corresponds to the solicited node multicast IPv6 address. This balances out the "network-up" calls that allow that MAC address. Removes the explicit broadcast MAC check in eConsiderFrameForProcessing. Broadcasts are a form of multicasts and will be received when ipconfigSUPPORT_IP_MULTICAST is enabled. Adds ipconfigSUPPORT_IP_MULTICAST to enable/disable all the functionality described above. Adds ipconfigPERIODIC_MULTICAST_REPORT_INTERVAL for debug purposes when there is no IGMP/MLD querier Moves the registration of the IGMP multicast MAC to the network driver init code. Adds a Multicast Todo list to help keep me on track.
I'm starting a PR in order to quit procrastinating on this subject and to align my ideas with the rest of the community. This is my proposal for how multicast can be added. Please feel free to comment.
This is nowhere near done, but it is functional and I am using it in my projects.
If you want to to try this, you will have to modify your network driver to receive multicast packets. I only have ATSAME70 hardware so that is the only network driver that this PR updates.
As of the time of this PR's creation, the code only supports IPv4. It also supports multiple groups per socket, but this will be removed in the interest of lower CPU load. The goal is for 1 socket to only be able to subscribe to 1 multicast group.
Commit details:
Adds 2 function pointers to the network interface struct that handle adding and removing multicast MAC addresses. Updates IGMP to use function pointers through the network interface. Makes the Add/Remove Multicast functions private to NetworkInterface.c They are now used through pointers in the NetworkInterface_t struct. Improves the SAME70 driver to handle adding/removing muticast MAC addresses