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);

Reply via email to