@@ -36,6 +36,9 @@ const (
3636	kubeNetworkPolicyChainPrefix  =  "KUBE-NWPLCY-" 
3737	kubeSourceIpSetPrefix         =  "KUBE-SRC-" 
3838	kubeDestinationIpSetPrefix    =  "KUBE-DST-" 
39+ 	kubeInputChainName            =  "KUBE-ROUTER-INPUT" 
40+ 	kubeForwardChainName          =  "KUBE-ROUTER-FORWARD" 
41+ 	kubeOutputChainName           =  "KUBE-ROUTER-OUTPUT" 
3942)
4043
4144// Network policy controller provides both ingress and egress filtering for the pods as per the defined network 
@@ -141,6 +144,9 @@ func (npc *NetworkPolicyController) Run(healthChan chan<- *healthcheck.Controlle
141144	glog .Info ("Starting network policy controller" )
142145	npc .healthChan  =  healthChan 
143146
147+ 	// setup kube-router specific top level cutoms chains 
148+ 	npc .ensureTopLevelChains ()
149+ 
144150	// Full syncs of the network policy controller take a lot of time and can only be processed one at a time, 
145151	// therefore, we start it in it's own goroutine and request a sync through a single item channel 
146152	glog .Info ("Starting network policy controller full sync goroutine" )
@@ -179,6 +185,62 @@ func (npc *NetworkPolicyController) Run(healthChan chan<- *healthcheck.Controlle
179185	}
180186}
181187
188+ // Creates custom chains KUBE-ROUTER-INPUT, KUBE-ROUTER-FORWARD, KUBE-ROUTER-OUTPUT 
189+ // and following rules in the filter table to jump from builtin chain to custom chain 
190+ // -A INPUT   -m comment --comment "kube-router netpol" -j KUBE-ROUTER-INPUT 
191+ // -A FORWARD -m comment --comment "kube-router netpol" -j KUBE-ROUTER-FORWARD 
192+ // -A OUTPUT  -m comment --comment "kube-router netpol" -j KUBE-ROUTER-OUTPUT 
193+ func  (npc  * NetworkPolicyController ) ensureTopLevelChains () {
194+ 
195+ 	iptablesCmdHandler , err  :=  iptables .New ()
196+ 	if  err  !=  nil  {
197+ 		glog .Fatalf ("Failed to initialize iptables executor due to %s" , err .Error ())
198+ 	}
199+ 
200+ 	chains  :=  map [string ]string {"INPUT" : kubeInputChainName , "FORWARD" : kubeForwardChainName , "OUTPUT" : kubeOutputChainName }
201+ 
202+ 	for  builtinChain , customChain  :=  range  chains  {
203+ 		err  =  iptablesCmdHandler .NewChain ("filter" , customChain )
204+ 		if  err  !=  nil  &&  err .(* iptables.Error ).ExitStatus () !=  1  {
205+ 			glog .Fatalf ("Failed to run iptables command to create %s chain due to %s" , customChain , err .Error ())
206+ 		}
207+ 		args  :=  []string {"-m" , "comment" , "--comment" , "kube-router netpol" , "-j" , customChain }
208+ 		exists , err  :=  iptablesCmdHandler .Exists ("filter" , builtinChain , args ... )
209+ 		if  err  !=  nil  {
210+ 			glog .Fatalf ("Failed to verify rule exists to jump to chain %s in %s chain due to %s" , customChain , builtinChain , err .Error ())
211+ 		}
212+ 		if  ! exists  {
213+ 			err  :=  iptablesCmdHandler .Insert ("filter" , builtinChain , 1 , args ... )
214+ 			if  err  !=  nil  {
215+ 				glog .Fatalf ("Failed to run iptables command to insert in %s chain %s" , builtinChain , err .Error ())
216+ 			}
217+ 		} else  {
218+ 			rules , err  :=  iptablesCmdHandler .List ("filter" , builtinChain )
219+ 			if  err  !=  nil  {
220+ 				glog .Fatalf ("failed to list rules in filter table %s chain due to %s" , builtinChain , err .Error ())
221+ 			}
222+ 
223+ 			var  ruleNo  int 
224+ 			for  i , rule  :=  range  rules  {
225+ 				if  strings .Contains (rule , customChain ) {
226+ 					ruleNo  =  i 
227+ 					break 
228+ 				}
229+ 			}
230+ 			if  ruleNo  !=  1  {
231+ 				err  =  iptablesCmdHandler .Insert ("filter" , builtinChain , 1 , args ... )
232+ 				if  err  !=  nil  {
233+ 					glog .Fatalf ("Failed to run iptables command to insert in %s chain %s" , builtinChain , err .Error ())
234+ 				}
235+ 				err  =  iptablesCmdHandler .Delete ("filter" , builtinChain , strconv .Itoa (ruleNo + 1 ))
236+ 				if  err  !=  nil  {
237+ 					glog .Fatalf ("Failed to delete wrong rule to jump to chain %s in %s chain due to %s" , customChain , builtinChain , err .Error ())
238+ 				}
239+ 			}
240+ 		}
241+ 	}
242+ }
243+ 
182244// OnPodUpdate handles updates to pods from the Kubernetes api server 
183245func  (npc  * NetworkPolicyController ) OnPodUpdate (obj  interface {}) {
184246	pod  :=  obj .(* api.Pod )
@@ -225,6 +287,10 @@ func (npc *NetworkPolicyController) fullPolicySync() {
225287	}()
226288
227289	glog .V (1 ).Infof ("Starting sync of iptables with version: %s" , syncVersion )
290+ 
291+ 	// ensure kube-router specific top level chains and corresponding rules exist 
292+ 	npc .ensureTopLevelChains ()
293+ 
228294	if  npc .v1NetworkPolicy  {
229295		networkPoliciesInfo , err  =  npc .buildNetworkPoliciesInfo ()
230296		if  err  !=  nil  {
@@ -760,25 +826,25 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(networkPoliciesInfo []
760826		comment  =  "rule to jump traffic destined to POD name:"  +  pod .name  +  " namespace: "  +  pod .namespace  + 
761827			" to chain "  +  podFwChainName 
762828		args  =  []string {"-m" , "comment" , "--comment" , comment , "-d" , pod .ip , "-j" , podFwChainName }
763- 		exists , err  =  iptablesCmdHandler .Exists ("filter" , "FORWARD" , args ... )
829+ 		exists , err  =  iptablesCmdHandler .Exists ("filter" , kubeForwardChainName , args ... )
764830		if  err  !=  nil  {
765831			return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
766832		}
767833		if  ! exists  {
768- 			err  :=  iptablesCmdHandler .Insert ("filter" , "FORWARD" , 1 , args ... )
834+ 			err  :=  iptablesCmdHandler .Insert ("filter" , kubeForwardChainName , 1 , args ... )
769835			if  err  !=  nil  {
770836				return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
771837			}
772838		}
773839
774840		// ensure there is rule in filter table and OUTPUT chain to jump to pod specific firewall chain 
775841		// this rule applies to the traffic from a pod getting routed back to another pod on same node by service proxy 
776- 		exists , err  =  iptablesCmdHandler .Exists ("filter" , "OUTPUT" , args ... )
842+ 		exists , err  =  iptablesCmdHandler .Exists ("filter" , kubeOutputChainName , args ... )
777843		if  err  !=  nil  {
778844			return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
779845		}
780846		if  ! exists  {
781- 			err  :=  iptablesCmdHandler .Insert ("filter" , "OUTPUT" , 1 , args ... )
847+ 			err  :=  iptablesCmdHandler .Insert ("filter" , kubeOutputChainName , 1 , args ... )
782848			if  err  !=  nil  {
783849				return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
784850			}
@@ -792,12 +858,12 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(networkPoliciesInfo []
792858			"-m" , "comment" , "--comment" , comment ,
793859			"-d" , pod .ip ,
794860			"-j" , podFwChainName }
795- 		exists , err  =  iptablesCmdHandler .Exists ("filter" , "FORWARD" , args ... )
861+ 		exists , err  =  iptablesCmdHandler .Exists ("filter" , kubeForwardChainName , args ... )
796862		if  err  !=  nil  {
797863			return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
798864		}
799865		if  ! exists  {
800- 			err  =  iptablesCmdHandler .Insert ("filter" , "FORWARD" , 1 , args ... )
866+ 			err  =  iptablesCmdHandler .Insert ("filter" , kubeForwardChainName , 1 , args ... )
801867			if  err  !=  nil  {
802868				return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
803869			}
@@ -874,7 +940,7 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(networkPoliciesInfo []
874940			}
875941		}
876942
877- 		egressFilterChains  :=  []string {"FORWARD" ,  "OUTPUT" ,  "INPUT" }
943+ 		egressFilterChains  :=  []string {kubeInputChainName ,  kubeForwardChainName ,  kubeOutputChainName }
878944		for  _ , chain  :=  range  egressFilterChains  {
879945			// ensure there is rule in filter table and FORWARD chain to jump to pod specific firewall chain 
880946			// this rule applies to the traffic getting forwarded/routed (traffic from the pod destinted 
@@ -902,12 +968,12 @@ func (npc *NetworkPolicyController) syncPodFirewallChains(networkPoliciesInfo []
902968			"-m" , "comment" , "--comment" , comment ,
903969			"-s" , pod .ip ,
904970			"-j" , podFwChainName }
905- 		exists , err  =  iptablesCmdHandler .Exists ("filter" , "FORWARD" , args ... )
971+ 		exists , err  =  iptablesCmdHandler .Exists ("filter" , kubeForwardChainName , args ... )
906972		if  err  !=  nil  {
907973			return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
908974		}
909975		if  ! exists  {
910- 			err  =  iptablesCmdHandler .Insert ("filter" , "FORWARD" , 1 , args ... )
976+ 			err  =  iptablesCmdHandler .Insert ("filter" , kubeForwardChainName , 1 , args ... )
911977			if  err  !=  nil  {
912978				return  nil , fmt .Errorf ("Failed to run iptables command: %s" , err .Error ())
913979			}
@@ -982,7 +1048,7 @@ func cleanupStaleRules(activePolicyChains, activePodFwChains, activePolicyIPSets
9821048	// remove stale iptables podFwChain references from the filter table chains 
9831049	for  _ , podFwChain  :=  range  cleanupPodFwChains  {
9841050
985- 		primaryChains  :=  []string {"FORWARD" ,  "OUTPUT" ,  "INPUT" }
1051+ 		primaryChains  :=  []string {kubeInputChainName ,  kubeForwardChainName ,  kubeOutputChainName }
9861052		for  _ , egressChain  :=  range  primaryChains  {
9871053			forwardChainRules , err  :=  iptablesCmdHandler .List ("filter" , egressChain )
9881054			if  err  !=  nil  {
@@ -1536,7 +1602,7 @@ func (npc *NetworkPolicyController) Cleanup() {
15361602	}
15371603
15381604	// delete jump rules in FORWARD chain to pod specific firewall chain 
1539- 	forwardChainRules , err  :=  iptablesCmdHandler .List ("filter" , "FORWARD" )
1605+ 	forwardChainRules , err  :=  iptablesCmdHandler .List ("filter" , kubeForwardChainName )
15401606	if  err  !=  nil  {
15411607		glog .Errorf ("Failed to delete iptables rules as part of cleanup" )
15421608		return 
@@ -1546,7 +1612,7 @@ func (npc *NetworkPolicyController) Cleanup() {
15461612	var  realRuleNo  int 
15471613	for  i , rule  :=  range  forwardChainRules  {
15481614		if  strings .Contains (rule , kubePodFirewallChainPrefix ) {
1549- 			err  =  iptablesCmdHandler .Delete ("filter" , "FORWARD" , strconv .Itoa (i - realRuleNo ))
1615+ 			err  =  iptablesCmdHandler .Delete ("filter" , kubeForwardChainName , strconv .Itoa (i - realRuleNo ))
15501616			if  err  !=  nil  {
15511617				glog .Errorf ("Failed to delete iptables rule as part of cleanup: %s" , err )
15521618			}
@@ -1555,7 +1621,7 @@ func (npc *NetworkPolicyController) Cleanup() {
15551621	}
15561622
15571623	// delete jump rules in OUTPUT chain to pod specific firewall chain 
1558- 	forwardChainRules , err  =  iptablesCmdHandler .List ("filter" , "OUTPUT" )
1624+ 	forwardChainRules , err  =  iptablesCmdHandler .List ("filter" , kubeOutputChainName )
15591625	if  err  !=  nil  {
15601626		glog .Errorf ("Failed to delete iptables rules as part of cleanup" )
15611627		return 
@@ -1565,7 +1631,7 @@ func (npc *NetworkPolicyController) Cleanup() {
15651631	realRuleNo  =  0 
15661632	for  i , rule  :=  range  forwardChainRules  {
15671633		if  strings .Contains (rule , kubePodFirewallChainPrefix ) {
1568- 			err  =  iptablesCmdHandler .Delete ("filter" , "OUTPUT" , strconv .Itoa (i - realRuleNo ))
1634+ 			err  =  iptablesCmdHandler .Delete ("filter" , kubeOutputChainName , strconv .Itoa (i - realRuleNo ))
15691635			if  err  !=  nil  {
15701636				glog .Errorf ("Failed to delete iptables rule as part of cleanup: %s" , err )
15711637			}
0 commit comments