git: baad45c9c120 - main - inpcb: push multicast case local address selection logic into in_pcbladdr()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 22 Mar 2025 23:40:45 UTC
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=baad45c9c12028964acd0b58096f3aaa0fb22859 commit baad45c9c12028964acd0b58096f3aaa0fb22859 Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2025-03-22 23:37:37 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2025-03-22 23:37:37 +0000 inpcb: push multicast case local address selection logic into in_pcbladdr() When destination is multicast and inpcb has multicast options configured, we use completely different logic than in a normal case. Before this change, in in_pcbconnect() we would run in_pcbladdr() and then just ignore its results and run the multicast case block, that would override any earlier selection or failure. Let's embed the case in in_pcbladdr() and also check it earlier. Also, 69c05f428714 switched UDP unconnected sendto(2) to use in_pcbladdr() instead of in_pcbconnect_setup() and due to that lost the multicast case. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D49435 Fixes: 69c05f42871406b4b2b2dac00a268d1da0cacd3e --- sys/netinet/in_pcb.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 9a49353f1538..3774f73a7a8f 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1127,29 +1127,6 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred) if (in_nullhost(inp->inp_laddr)) { error = in_pcbladdr(inp, &faddr, &laddr, cred); - /* - * If the destination address is multicast and an outgoing - * interface has been set as a multicast option, prefer the - * address of that interface as our source address. - */ - if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && - inp->inp_moptions != NULL && - inp->inp_moptions->imo_multicast_ifp != NULL) { - struct ifnet *ifp = - inp->inp_moptions->imo_multicast_ifp; - struct in_ifaddr *ia; - - CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { - if (ia->ia_ifp == ifp && - prison_check_ip4(cred, - &ia->ia_addr.sin_addr) == 0) - break; - } - if (ia == NULL) - return (EADDRNOTAVAIL); - laddr = ia->ia_addr.sin_addr; - error = 0; - } if (error) return (error); } else @@ -1231,6 +1208,27 @@ in_pcbladdr(const struct inpcb *inp, struct in_addr *faddr, if (!prison_saddrsel_ip4(cred, laddr)) return (0); + /* + * If the destination address is multicast and an outgoing + * interface has been set as a multicast option, prefer the + * address of that interface as our source address. + */ + if (IN_MULTICAST(ntohl(faddr->s_addr)) && inp->inp_moptions != NULL && + inp->inp_moptions->imo_multicast_ifp != NULL) { + struct ifnet *ifp = inp->inp_moptions->imo_multicast_ifp; + struct in_ifaddr *ia; + + CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { + if (ia->ia_ifp == ifp && + prison_check_ip4(cred, &ia->ia_addr.sin_addr) == 0) + break; + } + if (ia == NULL) + return (EADDRNOTAVAIL); + *laddr = ia->ia_addr.sin_addr; + return (0); + } + error = 0; nh = NULL;