Static MC route was placed which had same (S,G) but with different NIC

#212 · closed · 3 comments

View on GitHub ↗

dtzq01

Hi, I met an issue: the static MC route was placed which had same (S,G) but with different NIC. Config: ens36: (192.168.3.21,225.0.0.1) => ens33 ens38: (192.168.3.21,225.0.0.1) => ens33 After config, only got the last one(ens38 => ens33). In kernel code, I saw NIC info lost when using MRT_ADD_MFC/MRT_DEL_MFC. Maybe MRT_ADD_MFC_PROXY/MRT_DEL_MFC_PROXY is a better choice. I've changed code and added same.sh as UT, it was OK here. See it in "Pull Request". Log:(Note the comment '//') ```bash code@code:~$ sudo smcroutectl add ens36 192.168.3.21 225.0.0.1 ens33 code@code:~$ sudo smcroutectl (*,G) Template Rules ROUTE (S,G) IIF OIFS (*, 225.0.0.1) ens36 (S,G) Rules ROUTE (S,G) IIF OIFS (192.168.3.21, 225.0.0.1) ens36 ens33 Kernel MFC Table ROUTE (S,G) IIF OIFS (192.168.3.21, 225.0.0.1) ens36 ens33 (192.168.248.1, 239.255.255.250) ens33 (192.168.23.1, 239.255.255.250) ens36 code@code:~$ ip mroute (192.168.248.1,239.255.255.250) Iif: ens33 State: resolved (192.168.23.1,239.255.255.250) Iif: ens36 State: resolved (192.168.3.21,225.0.0.1) Iif: ens36 Oifs: ens33 State: resolved //this would be replaced code@code:~$ sudo smcroutectl add ens38 192.168.3.21 225.0.0.1 ens33 code@code:~$ sudo smcroutectl (*,G) Template Rules ROUTE (S,G) IIF OIFS (*, 225.0.0.1) ens36 (S,G) Rules ROUTE (S,G) IIF OIFS (192.168.3.21, 225.0.0.1) ens36 ens33 (192.168.3.21, 225.0.0.1) ens38 ens33 Kernel MFC Table ROUTE (S,G) IIF OIFS (192.168.3.21, 225.0.0.1) ens36 ens33 (192.168.3.21, 225.0.0.1) ens38 ens33 (192.168.248.1, 239.255.255.250) ens33 (192.168.23.1, 239.255.255.250) ens36 code@code:~$ ip mroute (192.168.3.21,225.0.0.1) Iif: ens38 Oifs: ens33 State: resolved //Not added, replaced the ens36 route. (192.168.23.1,239.255.255.250) Iif: ens36 State: resolved (192.168.248.1,239.255.255.250) Iif: ens33 State: resolved code@code:~$ ``` Kernel code(ipmr.c) ``` int ip_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval, unsigned int optlen) { ... case MRT_ADD_MFC: case MRT_DEL_MFC: parent = -1; //lost NIC info here fallthrough; case MRT_ADD_MFC_PROXY: case MRT_DEL_MFC_PROXY: if (optlen != sizeof(mfc)) { ret = -EINVAL; break; } if (copy_from_sockptr(&mfc, optval, sizeof(mfc))) { ret = -EFAULT; break; } if (parent == 0) parent = mfc.mfcc_parent; if (optname == MRT_DEL_MFC || optname == MRT_DEL_MFC_PROXY) ret = ipmr_mfc_delete(mrt, &mfc, parent); else ret = ipmr_mfc_add(net, mrt, &mfc, sk == rtnl_dereference(mrt->mroute_sk), parent); break; ... } ```

Comments

troglobit

I'm afraid this is a use-case that SMCRoute can never support. Having the same (S,G) ingressing two different interfaces is usually a sign of a layer-3 loop, or a switch-over in a layer-3 topology change. What is the setup you are using to get this? A dynamic multicast routing daemon would in a case like this get a notification from the kernel; "Hey, remember that (S,G) we have installed on interface A? It's started arriving on interface B ...". Which would prompt the daemon to inspect the *unicast* routing table for the reverse-path to S -- if S has moved from A to B, the multicast route is updated, if not, and it's still behind A, the daemon waits. Also, the new `MRT_ADD_MFC_PROXY` and `MRT_DEL_MFC_PROXY` sockopts introduced in Linux are not available on other UNIX systems which SMCRoute supports, so we cannot simply switch to them just because this "fix" somehow works for you. I suggest looking into another solution, maybe the various multicast proxy implementations instead: [igmpproxy](https://github.com/pali/igmpproxy) and [mcproxy](https://github.com/mcproxy/mcproxy).

dtzq01

Thank you for your response; I now have a deeper understanding of the SMCROUTE situation. The scenario is as follows: NIC-A and NIC-B are actually connected to two physically isolated networks, but logically they belong to the same department and both have the requirement to send multicast traffic to NIC-C. As a multicast service for (S,G), I am not sure whether the multicast data will come from NIC-A or NIC-B, so I have added two static multicast routes to accommodate the possible multicast forwarding. Additionally, thank you for your suggestions regarding igmpproxy and mcproxy.

troglobit

In such complex setups one usually have to use SNAT in the prerouting chain.