@@ -19,6 +19,7 @@ func configureInterface(iface netlink.Link, settings *Interface) error {
1919 {setInterfaceName , fmt .Sprintf ("error renaming interface %q to %q" , ifaceName , settings .DstName )},
2020 {setInterfaceIP , fmt .Sprintf ("error setting interface %q IP to %q" , ifaceName , settings .Address )},
2121 {setInterfaceIPv6 , fmt .Sprintf ("error setting interface %q IPv6 to %q" , ifaceName , settings .AddressIPv6 )},
22+ {setInterfaceRoutes , fmt .Sprintf ("error setting interface %q routes to %q" , ifaceName , settings .Routes )},
2223 }
2324
2425 for _ , config := range ifaceConfigurators {
@@ -63,6 +64,78 @@ func programGateway(path string, gw net.IP) error {
6364 })
6465}
6566
67+ // Program a route in to the namespace routing table.
68+ func programRoute (path string , dest * net.IPNet , nh net.IP ) error {
69+ runtime .LockOSThread ()
70+ defer runtime .UnlockOSThread ()
71+
72+ origns , err := netns .Get ()
73+ if err != nil {
74+ return err
75+ }
76+ defer origns .Close ()
77+
78+ f , err := os .OpenFile (path , os .O_RDONLY , 0 )
79+ if err != nil {
80+ return fmt .Errorf ("failed get network namespace %q: %v" , path , err )
81+ }
82+ defer f .Close ()
83+
84+ nsFD := f .Fd ()
85+ if err = netns .Set (netns .NsHandle (nsFD )); err != nil {
86+ return err
87+ }
88+ defer netns .Set (origns )
89+
90+ gwRoutes , err := netlink .RouteGet (nh )
91+ if err != nil {
92+ return fmt .Errorf ("route for the next hop could not be found: %v" , err )
93+ }
94+
95+ return netlink .RouteAdd (& netlink.Route {
96+ Scope : netlink .SCOPE_UNIVERSE ,
97+ LinkIndex : gwRoutes [0 ].LinkIndex ,
98+ Gw : gwRoutes [0 ].Gw ,
99+ Dst : dest ,
100+ })
101+ }
102+
103+ // Delete a route from the namespace routing table.
104+ func removeRoute (path string , dest * net.IPNet , nh net.IP ) error {
105+ runtime .LockOSThread ()
106+ defer runtime .UnlockOSThread ()
107+
108+ origns , err := netns .Get ()
109+ if err != nil {
110+ return err
111+ }
112+ defer origns .Close ()
113+
114+ f , err := os .OpenFile (path , os .O_RDONLY , 0 )
115+ if err != nil {
116+ return fmt .Errorf ("failed get network namespace %q: %v" , path , err )
117+ }
118+ defer f .Close ()
119+
120+ nsFD := f .Fd ()
121+ if err = netns .Set (netns .NsHandle (nsFD )); err != nil {
122+ return err
123+ }
124+ defer netns .Set (origns )
125+
126+ gwRoutes , err := netlink .RouteGet (nh )
127+ if err != nil {
128+ return fmt .Errorf ("route for the next hop could not be found: %v" , err )
129+ }
130+
131+ return netlink .RouteDel (& netlink.Route {
132+ Scope : netlink .SCOPE_UNIVERSE ,
133+ LinkIndex : gwRoutes [0 ].LinkIndex ,
134+ Gw : gwRoutes [0 ].Gw ,
135+ Dst : dest ,
136+ })
137+ }
138+
66139func setInterfaceIP (iface netlink.Link , settings * Interface ) error {
67140 ipAddr := & netlink.Addr {IPNet : settings .Address , Label : "" }
68141 return netlink .AddrAdd (iface , ipAddr )
@@ -79,3 +152,17 @@ func setInterfaceIPv6(iface netlink.Link, settings *Interface) error {
79152func setInterfaceName (iface netlink.Link , settings * Interface ) error {
80153 return netlink .LinkSetName (iface , settings .DstName )
81154}
155+
156+ func setInterfaceRoutes (iface netlink.Link , settings * Interface ) error {
157+ for _ , route := range settings .Routes {
158+ err := netlink .RouteAdd (& netlink.Route {
159+ Scope : netlink .SCOPE_UNIVERSE ,
160+ LinkIndex : iface .Attrs ().Index ,
161+ Dst : route ,
162+ })
163+ if err != nil {
164+ return err
165+ }
166+ }
167+ return nil
168+ }
0 commit comments