Raw sockets do not comply with route sourceaddr.
Use set address if source is not set by the caller.
Index: netinet/ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.377
diff -u -p -r1.377 ip_output.c
--- netinet/ip_output.c 3 Dec 2021 17:18:34 -0000 1.377
+++ netinet/ip_output.c 16 Dec 2021 18:12:44 -0000
@@ -110,6 +110,7 @@ ip_output(struct mbuf *m, struct mbuf *o
struct route iproute;
struct sockaddr_in *dst;
struct tdb *tdb = NULL;
+ struct sockaddr *ip4_source = NULL;
u_long mtu;
#if NPF > 0
u_int orig_rtableid;
@@ -237,8 +238,18 @@ reroute:
dst = satosin(ro->ro_rt->rt_gateway);
/* Set the source IP address */
- if (ip->ip_src.s_addr == INADDR_ANY && ia)
- ip->ip_src = ia->ia_addr.sin_addr;
+ if (ip->ip_src.s_addr == INADDR_ANY && ia) {
+ ip4_source = rtable_getsource(ro->ro_tableid, AF_INET);
+ if (ip4_source != NULL) {
+ struct ifaddr *ifa;
+ if ((ifa = ifa_ifwithaddr(ip4_source,
+ ro->ro_tableid)) != NULL &&
+ ISSET(ifa->ifa_ifp->if_flags, IFF_UP)) {
+ ip->ip_src =
satosin(ip4_source)->sin_addr;
+ }
+ } else
+ ip->ip_src = ia->ia_addr.sin_addr;
+ }
}
#ifdef IPSEC