On Thu, Apr 07, 2011 at 10:47:41AM -0300, Christiano F. Haesbaert wrote:
> Keeping this up.
>
> On 17 March 2011 00:51, Christiano F. Haesbaert <[email protected]>
> wrote:
> > On 12 June 2010 16:26, Christiano F. Haesbaert <[email protected]>
> wrote:
> >> Hi,
> >>
> >> The following will disregard the routing table for multicast packets
> >> when the application chose the interface with IP_MULTICAST_IF, if not,
> >> normal lookup will take place.
> >>
> >> Ripd now no longer needs to explicitly add the mcast host route to
> >> bypass the default reject to 224/4, follows the diff to remove it.
> >>
> >> Regarding the normal lookup when IP_MULTICAST_IF wan't set, UNP
> >> regards it as a BSD descendant behaviour, I really don't know anything
> >> else.
> >>
> >> I've tested it in a small setup, if someone could confirm it in a
> >> scarier environment would be nice.
> >>
What about this version? It moves the multicast source selection before
the route selection. IMO this is a nicer way to write this instead of
making an already complex if statement totaly unreadable.
In the end this will help more daemons to run with multicast_host=NO
when doing multicast. It also matches the behaviour of SOCK_RAW sockets
since those bypass this code and so don't suffer from the blackhole route
added by /etc/netstart.
--
:wq Claudio
Index: in_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.119
diff -u -p -r1.119 in_pcb.c
--- in_pcb.c 28 Apr 2011 09:56:27 -0000 1.119
+++ in_pcb.c 28 Apr 2011 10:35:38 -0000
@@ -824,6 +824,27 @@ in_selectsrc(struct sockaddr_in *sin, st
ia = (struct in_ifaddr *)0;
/*
+ * If the destination address is multicast and an outgoing
+ * interface has been set as a multicast option, use the
+ * address of that interface as our source address.
+ */
+ if (IN_MULTICAST(sin->sin_addr.s_addr) && mopts != NULL) {
+ struct ifnet *ifp;
+
+ if (mopts->imo_multicast_ifp != NULL) {
+ ifp = mopts->imo_multicast_ifp;
+ TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
+ if (ia->ia_ifp == ifp &&
+ rtable_l2(rtableid) == ifp->if_rdomain)
+ break;
+ if (ia == 0) {
+ *errorp = EADDRNOTAVAIL;
+ return NULL;
+ }
+ return satosin(&ia->ia_addr);
+ }
+ }
+ /*
* If route is known or can be allocated now,
* our src addr is taken from the i/f, else punt.
*/
@@ -872,27 +893,6 @@ in_selectsrc(struct sockaddr_in *sin, st
if (ia == 0) {
*errorp = EADDRNOTAVAIL;
return NULL;
- }
- }
- /*
- * If the destination address is multicast and an outgoing
- * interface has been set as a multicast option, use the
- * address of that interface as our source address.
- */
- if (IN_MULTICAST(sin->sin_addr.s_addr) && mopts != NULL) {
- struct ip_moptions *imo;
- struct ifnet *ifp;
-
- imo = mopts;
- if (imo->imo_multicast_ifp != NULL) {
- ifp = imo->imo_multicast_ifp;
- TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
- if (ia->ia_ifp == ifp)
- break;
- if (ia == 0) {
- *errorp = EADDRNOTAVAIL;
- return NULL;
- }
}
}
return satosin(&ia->ia_addr);