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

Reply via email to