@@ -76,6 +76,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
7676 Flags : int (netlink .FLAG_ONLINK ),
7777 Gw : segment .privateIPs [i ],
7878 LinkIndex : tunlIface ,
79+ Src : t .privateIP .IP ,
7980 Protocol : unix .RTPROT_STATIC ,
8081 Table : kiloTableIndex ,
8182 })
@@ -135,6 +136,14 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
135136 }
136137 return routes , rules
137138 }
139+ // Compute the preferred source address for routes through the WireGuard interface.
140+ // Without this, the kernel picks the WireGuard overlay IP (e.g. 100.66.0.x) as the
141+ // source, which can cause issues in environments like Azure SDN where the overlay
142+ // IP is unknown to the network fabric and reply packets cannot be routed back.
143+ var src net.IP
144+ if t .privateIP != nil {
145+ src = t .privateIP .IP
146+ }
138147 for _ , segment := range t .segments {
139148 // Add routes for the current segment if local is true.
140149 if segment .location == t .location {
@@ -161,6 +170,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
161170 Flags : int (netlink .FLAG_ONLINK ),
162171 Gw : segment .privateIPs [i ],
163172 LinkIndex : tunlIface ,
173+ Src : t .privateIP .IP ,
164174 Protocol : unix .RTPROT_STATIC ,
165175 Table : kiloTableIndex ,
166176 })
@@ -190,6 +200,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
190200 Flags : int (netlink .FLAG_ONLINK ),
191201 Gw : segment .wireGuardIP ,
192202 LinkIndex : kiloIface ,
203+ Src : src ,
193204 Protocol : unix .RTPROT_STATIC ,
194205 })
195206 // Don't add routes through Kilo if the private IP
@@ -207,6 +218,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
207218 Flags : int (netlink .FLAG_ONLINK ),
208219 Gw : segment .wireGuardIP ,
209220 LinkIndex : kiloIface ,
221+ Src : src ,
210222 Protocol : unix .RTPROT_STATIC ,
211223 })
212224 }
@@ -218,6 +230,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
218230 Flags : int (netlink .FLAG_ONLINK ),
219231 Gw : segment .wireGuardIP ,
220232 LinkIndex : kiloIface ,
233+ Src : src ,
221234 Protocol : unix .RTPROT_STATIC ,
222235 })
223236 }
@@ -228,6 +241,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
228241 routes = append (routes , & netlink.Route {
229242 Dst : & peer .AllowedIPs [i ],
230243 LinkIndex : kiloIface ,
244+ Src : src ,
231245 Protocol : unix .RTPROT_STATIC ,
232246 })
233247 }
@@ -304,8 +318,11 @@ func (t *Topology) PeerRoutes(name string, kiloIface int, additionalAllowedIPs [
304318}
305319
306320func encapsulateRoute (route * netlink.Route , encapsulate encapsulation.Strategy , subnet * net.IPNet , tunlIface int ) * netlink.Route {
307- if encapsulate == encapsulation .Always || (encapsulate == encapsulation .CrossSubnet && ! subnet .Contains (route .Gw )) {
321+ if encapsulate == encapsulation .Always || (encapsulate == encapsulation .CrossSubnet && subnet != nil && ! subnet .Contains (route .Gw )) {
308322 route .LinkIndex = tunlIface
323+ if subnet != nil && route .Src == nil {
324+ route .Src = subnet .IP
325+ }
309326 }
310327 return route
311328}
0 commit comments