Re: in_pcbbind() and in_broadcast/in_iawithaddr
On 3 June 2014 09:18, Martin Pieuchot mpieuc...@nolizard.org wrote: On 02/06/14(Mon) 15:45, Martin Pieuchot wrote: This diff is similar to the one that has been committed to handle the SOCK_RAW binding. I'd like to stop using in_iawithaddr() *and* in_broadcast(). Since these functions are just doing an iteration on all the addresses present in the RB-tree (or equivalent), let's use ifa_ifwithaddr() instead. This diff should not introduce any behavior change concerning SOCK_DGRAM and binding to multicast addresses. As pointed out by jca@ this diff breaks on loopback. This is because the loopback IPv4 addresses are abusing the dstaddr field to be able to create a route to their address. Hopefully this hack can be removed once the local route diff is in, but in the meantime let's use the less intuitive but equivalent idiom: sin-sin_addr.s_addr != ia-ia_addr.s_addr Update diff below, is this one ok? OK
Re: in_pcbbind() and in_broadcast/in_iawithaddr
On 02/06/14(Mon) 15:45, Martin Pieuchot wrote: This diff is similar to the one that has been committed to handle the SOCK_RAW binding. I'd like to stop using in_iawithaddr() *and* in_broadcast(). Since these functions are just doing an iteration on all the addresses present in the RB-tree (or equivalent), let's use ifa_ifwithaddr() instead. This diff should not introduce any behavior change concerning SOCK_DGRAM and binding to multicast addresses. As pointed out by jca@ this diff breaks on loopback. This is because the loopback IPv4 addresses are abusing the dstaddr field to be able to create a route to their address. Hopefully this hack can be removed once the local route diff is in, but in the meantime let's use the less intuitive but equivalent idiom: sin-sin_addr.s_addr != ia-ia_addr.s_addr Update diff below, is this one ok? Index: netinet/in_pcb.c === RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.155 diff -u -p -r1.155 in_pcb.c --- netinet/in_pcb.c7 May 2014 08:26:38 - 1.155 +++ netinet/in_pcb.c3 Jun 2014 07:12:53 - @@ -261,14 +261,22 @@ in_pcbbind(struct inpcb *inp, struct mbu reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (sin-sin_addr.s_addr != INADDR_ANY) { sin-sin_port = 0; /* yech... */ - if (!(so-so_options SO_BINDANY) - in_iawithaddr(sin-sin_addr, - inp-inp_rtableid) == NULL) + if (!((so-so_options SO_BINDANY) || + (sin-sin_addr.s_addr == INADDR_BROADCAST +so-so_type == SOCK_DGRAM))) { + struct in_ifaddr *ia; + + ia = ifatoia(ifa_ifwithaddr(sintosa(sin), + inp-inp_rtableid)); + if (ia == NULL) +return (EADDRNOTAVAIL); + /* SOCK_RAW does not use in_pcbbind() */ - if (!(so-so_type == SOCK_DGRAM - in_broadcast(sin-sin_addr, NULL, - inp-inp_rtableid))) - return (EADDRNOTAVAIL); + if (so-so_type != SOCK_DGRAM + sin-sin_addr.s_addr != + ia-ia_addr.sin_addr.s_addr) +return (EADDRNOTAVAIL); + } } if (lport) { struct inpcb *t;
Re: in_pcbbind() and in_broadcast/in_iawithaddr
Martin Pieuchot mpieuc...@nolizard.org writes: [...] Update diff below, is this one ok? Looks correct; ok. [...] -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
in_pcbbind() and in_broadcast/in_iawithaddr
This diff is similar to the one that has been committed to handle the SOCK_RAW binding. I'd like to stop using in_iawithaddr() *and* in_broadcast(). Since these functions are just doing an iteration on all the addresses present in the RB-tree (or equivalent), let's use ifa_ifwithaddr() instead. This diff should not introduce any behavior change concerning SOCK_DGRAM and binding to multicast addresses. Ok? Index: netinet/in_pcb.c === RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.155 diff -u -p -r1.155 in_pcb.c --- netinet/in_pcb.c7 May 2014 08:26:38 - 1.155 +++ netinet/in_pcb.c2 Jun 2014 13:37:59 - @@ -261,14 +261,19 @@ in_pcbbind(struct inpcb *inp, struct mbu reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (sin-sin_addr.s_addr != INADDR_ANY) { sin-sin_port = 0; /* yech... */ - if (!(so-so_options SO_BINDANY) - in_iawithaddr(sin-sin_addr, - inp-inp_rtableid) == NULL) + if (!((so-so_options SO_BINDANY) || + (sin-sin_addr.s_addr == INADDR_BROADCAST +so-so_type == SOCK_DGRAM))) { + struct in_ifaddr *ia; + + ia = ifatoia(ifa_ifwithaddr(sintosa(sin), + inp-inp_rtableid)); /* SOCK_RAW does not use in_pcbbind() */ - if (!(so-so_type == SOCK_DGRAM - in_broadcast(sin-sin_addr, NULL, - inp-inp_rtableid))) - return (EADDRNOTAVAIL); + if (ia == NULL || (sin-sin_addr.s_addr == + ia-ia_broadaddr.sin_addr.s_addr + so-so_type != SOCK_DGRAM)) +return (EADDRNOTAVAIL); + } } if (lport) { struct inpcb *t;