@@ -26,6 +26,7 @@ import (
2626
2727func init () {
2828 reexec .Register ("fwmarker" , fwMarker )
29+ reexec .Register ("redirecter" , redirecter )
2930}
3031
3132func newService (name string , id string , ingressPorts []* PortConfig , aliases []string ) * service {
@@ -275,6 +276,12 @@ func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
275276 n := ep .getNetwork ()
276277 eIP := ep .Iface ().Address ()
277278
279+ if n .ingress {
280+ if err := addRedirectRules (sb .Key (), eIP , ep .ingressPorts ); err != nil {
281+ logrus .Errorf ("Failed to add redirect rules for ep %s: %v" , ep .Name (), err )
282+ }
283+ }
284+
278285 if sb .ingress {
279286 // For the ingress sandbox if this is not gateway
280287 // endpoint do nothing.
@@ -390,7 +397,7 @@ func (sb *sandbox) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*P
390397 }
391398
392399 logrus .Debugf ("Creating service for vip %s fwMark %d ingressPorts %#v" , vip , fwMark , ingressPorts )
393- if err := invokeFWMarker (sb .Key (), vip , fwMark , ingressPorts , filteredPorts , eIP , false ); err != nil {
400+ if err := invokeFWMarker (sb .Key (), vip , fwMark , ingressPorts , eIP , false ); err != nil {
394401 logrus .Errorf ("Failed to add firewall mark rule in sbox %s: %v" , sb .Key (), err )
395402 return
396403 }
@@ -461,7 +468,7 @@ func (sb *sandbox) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Po
461468 }
462469 }
463470
464- if err := invokeFWMarker (sb .Key (), vip , fwMark , ingressPorts , filteredPorts , eIP , true ); err != nil {
471+ if err := invokeFWMarker (sb .Key (), vip , fwMark , ingressPorts , eIP , true ); err != nil {
465472 logrus .Errorf ("Failed to add firewall mark rule in sbox %s: %v" , sb .Key (), err )
466473 }
467474 }
@@ -755,26 +762,17 @@ func readPortsFromFile(fileName string) ([]*PortConfig, error) {
755762
756763// Invoke fwmarker reexec routine to mark vip destined packets with
757764// the passed firewall mark.
758- func invokeFWMarker (path string , vip net.IP , fwMark uint32 , ingressPorts []* PortConfig , filteredPorts []* PortConfig , eIP * net.IPNet , isDelete bool ) error {
759- var (
760- ingressPortsFile string
761- filteredPortsFile string
762- )
765+ func invokeFWMarker (path string , vip net.IP , fwMark uint32 , ingressPorts []* PortConfig , eIP * net.IPNet , isDelete bool ) error {
766+ var ingressPortsFile string
763767
764768 if len (ingressPorts ) != 0 {
765769 var err error
766770 ingressPortsFile , err = writePortsToFile (ingressPorts )
767771 if err != nil {
768772 return err
769773 }
770- }
771774
772- if len (filteredPorts ) != 0 {
773- var err error
774- filteredPortsFile , err = writePortsToFile (filteredPorts )
775- if err != nil {
776- return err
777- }
775+ defer os .Remove (ingressPortsFile )
778776 }
779777
780778 addDelOpt := "-A"
@@ -784,7 +782,7 @@ func invokeFWMarker(path string, vip net.IP, fwMark uint32, ingressPorts []*Port
784782
785783 cmd := & exec.Cmd {
786784 Path : reexec .Self (),
787- Args : append ([]string {"fwmarker" }, path , vip .String (), fmt .Sprintf ("%d" , fwMark ), addDelOpt , ingressPortsFile , filteredPortsFile , eIP .String ()),
785+ Args : append ([]string {"fwmarker" }, path , vip .String (), fmt .Sprintf ("%d" , fwMark ), addDelOpt , ingressPortsFile , eIP .String ()),
788786 Stdout : os .Stdout ,
789787 Stderr : os .Stderr ,
790788 }
@@ -801,13 +799,12 @@ func fwMarker() {
801799 runtime .LockOSThread ()
802800 defer runtime .UnlockOSThread ()
803801
804- if len (os .Args ) < 8 {
802+ if len (os .Args ) < 7 {
805803 logrus .Error ("invalid number of arguments.." )
806804 os .Exit (1 )
807805 }
808806
809807 var ingressPorts []* PortConfig
810- var filteredPorts []* PortConfig
811808 if os .Args [5 ] != "" {
812809 var err error
813810 ingressPorts , err = readPortsFromFile (os .Args [5 ])
@@ -817,15 +814,6 @@ func fwMarker() {
817814 }
818815 }
819816
820- if os .Args [6 ] != "" {
821- var err error
822- filteredPorts , err = readPortsFromFile (os .Args [6 ])
823- if err != nil {
824- logrus .Errorf ("Failed reading filtered ports file: %v" , err )
825- os .Exit (7 )
826- }
827- }
828-
829817 vip := os .Args [2 ]
830818 fwMark , err := strconv .ParseUint (os .Args [3 ], 10 , 32 )
831819 if err != nil {
@@ -835,12 +823,6 @@ func fwMarker() {
835823 addDelOpt := os .Args [4 ]
836824
837825 rules := [][]string {}
838- for _ , iPort := range filteredPorts {
839- rule := strings .Fields (fmt .Sprintf ("-t nat %s PREROUTING -p %s --dport %d -j REDIRECT --to-port %d" ,
840- addDelOpt , strings .ToLower (PortConfig_Protocol_name [int32 (iPort .Protocol )]), iPort .PublishedPort , iPort .TargetPort ))
841- rules = append (rules , rule )
842- }
843-
844826 for _ , iPort := range ingressPorts {
845827 rule := strings .Fields (fmt .Sprintf ("-t mangle %s PREROUTING -p %s --dport %d -j MARK --set-mark %d" ,
846828 addDelOpt , strings .ToLower (PortConfig_Protocol_name [int32 (iPort .Protocol )]), iPort .PublishedPort , fwMark ))
@@ -860,9 +842,9 @@ func fwMarker() {
860842 }
861843
862844 if addDelOpt == "-A" {
863- eIP , subnet , err := net .ParseCIDR (os .Args [7 ])
845+ eIP , subnet , err := net .ParseCIDR (os .Args [6 ])
864846 if err != nil {
865- logrus .Errorf ("Failed to parse endpoint IP %s: %v" , os .Args [7 ], err )
847+ logrus .Errorf ("Failed to parse endpoint IP %s: %v" , os .Args [6 ], err )
866848 os .Exit (9 )
867849 }
868850
@@ -889,3 +871,82 @@ func fwMarker() {
889871 }
890872 }
891873}
874+
875+ func addRedirectRules (path string , eIP * net.IPNet , ingressPorts []* PortConfig ) error {
876+ var ingressPortsFile string
877+
878+ if len (ingressPorts ) != 0 {
879+ var err error
880+ ingressPortsFile , err = writePortsToFile (ingressPorts )
881+ if err != nil {
882+ return err
883+ }
884+ defer os .Remove (ingressPortsFile )
885+ }
886+
887+ cmd := & exec.Cmd {
888+ Path : reexec .Self (),
889+ Args : append ([]string {"redirecter" }, path , eIP .String (), ingressPortsFile ),
890+ Stdout : os .Stdout ,
891+ Stderr : os .Stderr ,
892+ }
893+
894+ if err := cmd .Run (); err != nil {
895+ return fmt .Errorf ("reexec failed: %v" , err )
896+ }
897+
898+ return nil
899+ }
900+
901+ // Redirecter reexec function.
902+ func redirecter () {
903+ runtime .LockOSThread ()
904+ defer runtime .UnlockOSThread ()
905+
906+ if len (os .Args ) < 4 {
907+ logrus .Error ("invalid number of arguments.." )
908+ os .Exit (1 )
909+ }
910+
911+ var ingressPorts []* PortConfig
912+ if os .Args [3 ] != "" {
913+ var err error
914+ ingressPorts , err = readPortsFromFile (os .Args [3 ])
915+ if err != nil {
916+ logrus .Errorf ("Failed reading ingress ports file: %v" , err )
917+ os .Exit (2 )
918+ }
919+ }
920+
921+ eIP , _ , err := net .ParseCIDR (os .Args [2 ])
922+ if err != nil {
923+ logrus .Errorf ("Failed to parse endpoint IP %s: %v" , os .Args [2 ], err )
924+ os .Exit (3 )
925+ }
926+
927+ rules := [][]string {}
928+ for _ , iPort := range ingressPorts {
929+ rule := strings .Fields (fmt .Sprintf ("-t nat -A PREROUTING -d %s -p %s --dport %d -j REDIRECT --to-port %d" ,
930+ eIP .String (), strings .ToLower (PortConfig_Protocol_name [int32 (iPort .Protocol )]), iPort .PublishedPort , iPort .TargetPort ))
931+ rules = append (rules , rule )
932+ }
933+
934+ ns , err := netns .GetFromPath (os .Args [1 ])
935+ if err != nil {
936+ logrus .Errorf ("failed get network namespace %q: %v" , os .Args [1 ], err )
937+ os .Exit (4 )
938+ }
939+ defer ns .Close ()
940+
941+ if err := netns .Set (ns ); err != nil {
942+ logrus .Errorf ("setting into container net ns %v failed, %v" , os .Args [1 ], err )
943+ os .Exit (5 )
944+ }
945+
946+ for _ , rule := range rules {
947+ if err := iptables .RawCombinedOutputNative (rule ... ); err != nil {
948+ logrus .Errorf ("setting up rule failed, %v: %v" , rule , err )
949+ os .Exit (5 )
950+ }
951+ }
952+ }
0 commit comments