@@ -18,6 +18,7 @@ import (
18
18
"github.com/moby/ipvs"
19
19
"github.com/vishvananda/netlink"
20
20
"github.com/vishvananda/netns"
21
+ "golang.org/x/sys/unix"
21
22
"k8s.io/klog/v2"
22
23
)
23
24
@@ -129,6 +130,7 @@ func (ln *linuxNetworking) ipAddrDel(iface netlink.Link, ip string, nodeIP strin
129
130
func (ln * linuxNetworking ) ipAddrAdd (iface netlink.Link , ip string , nodeIP string , addRoute bool ) error {
130
131
var netMask net.IPMask
131
132
var ipRouteCmdArgs []string
133
+ var isIPv6 bool
132
134
parsedIP := net .ParseIP (ip )
133
135
parsedNodeIP := net .ParseIP (nodeIP )
134
136
if parsedIP .To4 () != nil {
@@ -139,6 +141,7 @@ func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string, nodeIP strin
139
141
140
142
netMask = net .CIDRMask (ipv4NetMaskBits , ipv4NetMaskBits )
141
143
ipRouteCmdArgs = make ([]string , 0 )
144
+ isIPv6 = false
142
145
} else {
143
146
// If we're supposed to add a route and the IP family of the NodeIP and the VIP IP don't match, we can't proceed
144
147
if addRoute && parsedNodeIP .To4 () != nil {
@@ -147,6 +150,7 @@ func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string, nodeIP strin
147
150
148
151
netMask = net .CIDRMask (ipv6NetMaskBits , ipv6NetMaskBits )
149
152
ipRouteCmdArgs = []string {"-6" }
153
+ isIPv6 = true
150
154
}
151
155
152
156
naddr := & netlink.Addr {IPNet : & net.IPNet {IP : parsedIP , Mask : netMask }, Scope : syscall .RT_SCOPE_LINK }
@@ -177,6 +181,33 @@ func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string, nodeIP strin
177
181
return err
178
182
}
179
183
184
+ // IPv6 address adds in iproute2 appear to create some misc routes that will interfere with the source routing that
185
+ // we attempt to do below and cuased the issue commented on above. We need to remove those before we attempt to
186
+ // create the source route below. See: https://github.com/cloudnativelabs/kube-router/issues/1698
187
+ if isIPv6 {
188
+ nRoute := & netlink.Route {
189
+ Dst : & net.IPNet {IP : parsedIP , Mask : netMask },
190
+ Table : unix .RT_TABLE_UNSPEC ,
191
+ }
192
+ routes , err := netlink .RouteListFiltered (netlink .FAMILY_V6 , nRoute ,
193
+ netlink .RT_FILTER_DST | netlink .RT_FILTER_TABLE )
194
+ if err != nil {
195
+ klog .Errorf ("failed to list routes for interface %s: %v" , iface .Attrs ().Name , err )
196
+ return err
197
+ }
198
+ for idx , route := range routes {
199
+ klog .V (1 ).Infof ("Checking route %s for interface %s..." , route , iface .Attrs ().Name )
200
+ // Looking for routes where the destination matches our VIP AND the source is either nil or not the node IP
201
+ if route .Src == nil || ! route .Src .Equal (parsedNodeIP ) {
202
+ klog .V (1 ).Infof ("Deleting route %s for interface %s..." , route , iface .Attrs ().Name )
203
+ err = netlink .RouteDel (& routes [idx ])
204
+ if err != nil {
205
+ klog .Errorf ("failed to delete route %s for interface %s: %v" , route , iface .Attrs ().Name , err )
206
+ }
207
+ }
208
+ }
209
+ }
210
+
180
211
return nil
181
212
}
182
213
0 commit comments