diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-05-29 13:22:54 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-05-29 13:22:54 +0000 |
commit | e466514d5f000ca57ccd20147abed06060f836b5 (patch) | |
tree | 4eb7dd58fbf8650e91ccd575e196ee40afe53153 /sys/netinet | |
parent | 16cb993a1babc4614540410c9c090ec9da917c71 (diff) |
Move the source address selection for multicast destinations that
specify the outgoing interface with a multicast option up. Doing
this before the route lookup allows multicast traffic to work even
when the default 224/4 reject route is installed. Raw IP and IPv6
already had this behaviour.
Based on work by Christiano F. Haesbaert. OK sthen@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in_pcb.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 91d274faa30..1b90198ee00 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.120 2011/05/13 14:31:16 oga Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.121 2011/05/29 13:22:53 claudio Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -809,6 +809,27 @@ in_selectsrc(struct sockaddr_in *sin, struct route *ro, int soopts, 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. */ @@ -859,27 +880,6 @@ in_selectsrc(struct sockaddr_in *sin, struct route *ro, int soopts, 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); } |