@@ -74,7 +74,7 @@ type ipvsCalls interface {
7474}
7575
7676type  netlinkCalls  interface  {
77- 	ipAddrAdd (iface  netlink.Link , ip  string ) error 
77+ 	ipAddrAdd (iface  netlink.Link , ip  string ,  addRoute   bool ) error 
7878	ipAddrDel (iface  netlink.Link , ip  string ) error 
7979	prepareEndpointForDsr (containerId  string , endpointIP  string , vip  string ) error 
8080	getKubeDummyInterface () (netlink.Link , error )
@@ -104,7 +104,10 @@ func (ln *linuxNetworking) ipAddrDel(iface netlink.Link, ip string) error {
104104	return  err 
105105}
106106
107- func  (ln  * linuxNetworking ) ipAddrAdd (iface  netlink.Link , ip  string ) error  {
107+ // utility method to assign an IP to an interface. Mainly used to assign service VIP's 
108+ // to kube-dummy-if. Also when DSR is used, used to assign VIP to dummy interface 
109+ // inside the container. 
110+ func  (ln  * linuxNetworking ) ipAddrAdd (iface  netlink.Link , ip  string , addRoute  bool ) error  {
108111	naddr  :=  & netlink.Addr {IPNet : & net.IPNet {IP : net .ParseIP (ip ), Mask : net .IPv4Mask (255 , 255 , 255 , 255 )}, Scope : syscall .RT_SCOPE_LINK }
109112	err  :=  netlink .AddrAdd (iface , naddr )
110113	if  err  !=  nil  &&  err .Error () !=  IFACE_HAS_ADDR  {
@@ -113,6 +116,15 @@ func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string) error {
113116		return  err 
114117	}
115118
119+ 	// When a service VIP is assigned to a dummy interface and accessed from host, in some of the 
120+ 	// case Linux source IP selection logix selects VIP itself as source leading to problems 
121+ 	// to avoid this an explicit entry is added to use node IP as source IP when accessing 
122+ 	// VIP from the host. Please see https://github.com/cloudnativelabs/kube-router/issues/376 
123+ 
124+ 	if  ! addRoute  {
125+ 		return  nil 
126+ 	}
127+ 
116128	// TODO: netlink.RouteReplace which is replacement for below command is not working as expected. Call succeeds but 
117129	// route is not replaced. For now do it with command. 
118130	out , err  :=  exec .Command ("ip" , "route" , "replace" , "local" , ip , "dev" , KUBE_DUMMY_IF , "table" , "local" , "proto" , "kernel" , "scope" , "host" , "src" ,
@@ -122,27 +134,35 @@ func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string) error {
122134	}
123135	return  nil 
124136}
137+ 
125138func  (ln  * linuxNetworking ) ipvsGetServices () ([]* ipvs.Service , error ) {
126139	return  ln .ipvsHandle .GetServices ()
127140}
141+ 
128142func  (ln  * linuxNetworking ) ipvsGetDestinations (ipvsSvc  * ipvs.Service ) ([]* ipvs.Destination , error ) {
129143	return  ln .ipvsHandle .GetDestinations (ipvsSvc )
130144}
145+ 
131146func  (ln  * linuxNetworking ) ipvsDelDestination (ipvsSvc  * ipvs.Service , ipvsDst  * ipvs.Destination ) error  {
132147	return  ln .ipvsHandle .DelDestination (ipvsSvc , ipvsDst )
133148}
149+ 
134150func  (ln  * linuxNetworking ) ipvsNewDestination (ipvsSvc  * ipvs.Service , ipvsDst  * ipvs.Destination ) error  {
135151	return  ln .ipvsHandle .NewDestination (ipvsSvc , ipvsDst )
136152}
153+ 
137154func  (ln  * linuxNetworking ) ipvsUpdateDestination (ipvsSvc  * ipvs.Service , ipvsDst  * ipvs.Destination ) error  {
138155	return  ln .ipvsHandle .UpdateDestination (ipvsSvc , ipvsDst )
139156}
157+ 
140158func  (ln  * linuxNetworking ) ipvsDelService (ipvsSvc  * ipvs.Service ) error  {
141159	return  ln .ipvsHandle .DelService (ipvsSvc )
142160}
161+ 
143162func  (ln  * linuxNetworking ) ipvsUpdateService (ipvsSvc  * ipvs.Service ) error  {
144163	return  ln .ipvsHandle .UpdateService (ipvsSvc )
145164}
165+ 
146166func  (ln  * linuxNetworking ) ipvsNewService (ipvsSvc  * ipvs.Service ) error  {
147167	return  ln .ipvsHandle .NewService (ipvsSvc )
148168}
@@ -526,7 +546,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
526546		}
527547
528548		// assign cluster IP of the service to the dummy interface so that its routable from the pod's on the node 
529- 		err  :=  nsc .ln .ipAddrAdd (dummyVipInterface , svc .clusterIP .String ())
549+ 		err  :=  nsc .ln .ipAddrAdd (dummyVipInterface , svc .clusterIP .String (),  true )
530550		if  err  !=  nil  {
531551			continue 
532552		}
@@ -636,7 +656,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
636656				}
637657			} else  {
638658				// ensure director with vip assigned 
639- 				err  :=  nsc .ln .ipAddrAdd (dummyVipInterface , externalIP )
659+ 				err  :=  nsc .ln .ipAddrAdd (dummyVipInterface , externalIP ,  true )
640660				if  err  !=  nil  &&  err .Error () !=  IFACE_HAS_ADDR  {
641661					glog .Errorf ("Failed to assign external ip %s to dummy interface %s due to %s" , externalIP , KUBE_DUMMY_IF , err .Error ())
642662				}
@@ -981,7 +1001,7 @@ func (ln *linuxNetworking) prepareEndpointForDsr(containerId string, endpointIP
9811001	}
9821002
9831003	// assign VIP to the KUBE_TUNNEL_IF interface 
984- 	err  =  ln .ipAddrAdd (tunIf , vip )
1004+ 	err  =  ln .ipAddrAdd (tunIf , vip ,  false )
9851005	if  err  !=  nil  &&  err .Error () !=  IFACE_HAS_ADDR  {
9861006		netns .Set (hostNetworkNamespaceHandle )
9871007		activeNetworkNamespaceHandle , err  =  netns .Get ()
0 commit comments