Skip to content

Commit f12efea

Browse files
Merge pull request #17043 from pravisankar/validate-nodeip
Automatic merge from submit-queue. Bug 1505266 - Validate node IP is local during sdn node initialization Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1505266
2 parents df394f2 + 75adfb4 commit f12efea

File tree

3 files changed

+87
-61
lines changed

3 files changed

+87
-61
lines changed

pkg/network/common/common.go

+33
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
kapi "k8s.io/kubernetes/pkg/api"
2323
"k8s.io/kubernetes/pkg/apis/extensions"
2424
kinternalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
25+
26+
"github.com/vishvananda/netlink"
2527
)
2628

2729
func HostSubnetToString(subnet *networkapi.HostSubnet) string {
@@ -276,3 +278,34 @@ func RegisterSharedInformerEventHandlers(kubeInformers kinternalinformers.Shared
276278
},
277279
})
278280
}
281+
282+
var (
283+
ErrorNetworkInterfaceNotFound = fmt.Errorf("could not find network interface")
284+
)
285+
286+
func GetLinkDetails(ip string) (netlink.Link, *net.IPNet, error) {
287+
links, err := netlink.LinkList()
288+
if err != nil {
289+
return nil, nil, err
290+
}
291+
292+
for _, link := range links {
293+
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
294+
if err != nil {
295+
glog.Warningf("Could not get addresses of interface %q: %v", link.Attrs().Name, err)
296+
continue
297+
}
298+
299+
for _, addr := range addrs {
300+
if addr.IP.String() == ip {
301+
_, ipNet, err := net.ParseCIDR(addr.IPNet.String())
302+
if err != nil {
303+
return nil, nil, fmt.Errorf("could not parse CIDR network from address %q: %v", ip, err)
304+
}
305+
return link, ipNet, nil
306+
}
307+
}
308+
}
309+
310+
return nil, nil, ErrorNetworkInterfaceNotFound
311+
}

pkg/network/node/egressip.go

+10-35
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ type egressIPWatcher struct {
5151
namespacesByVNID map[uint32]*namespaceEgress
5252
namespacesByEgressIP map[string]*namespaceEgress
5353

54-
localEgressLink netlink.Link
55-
localEgressNet *net.IPNet
56-
localEgressIPMaskLen int
54+
localEgressLink netlink.Link
55+
localEgressNet *net.IPNet
5756

5857
testModeChan chan string
5958
}
@@ -72,8 +71,10 @@ func newEgressIPWatcher(localIP string, oc *ovsController) *egressIPWatcher {
7271
}
7372

7473
func (eip *egressIPWatcher) Start(networkClient networkclient.Interface, iptables *NodeIPTables) error {
75-
if err := eip.findEgressLink(); err != nil {
76-
return fmt.Errorf("could not find egress network interface: %v", err)
74+
var err error
75+
if eip.localEgressLink, eip.localEgressNet, err = common.GetLinkDetails(eip.localIP); err != nil {
76+
// Not expected, should already be caught by node.New()
77+
return err
7778
}
7879

7980
eip.iptables = iptables
@@ -84,34 +85,6 @@ func (eip *egressIPWatcher) Start(networkClient networkclient.Interface, iptable
8485
return nil
8586
}
8687

87-
func (eip *egressIPWatcher) findEgressLink() error {
88-
links, err := netlink.LinkList()
89-
if err != nil {
90-
return err
91-
}
92-
for _, link := range links {
93-
addrs, err := netlink.AddrList(link, syscall.AF_INET)
94-
if err != nil {
95-
glog.Warningf("Could not get addresses of interface %q while trying to find egress interface: %v", link.Attrs().Name, err)
96-
continue
97-
}
98-
99-
for _, addr := range addrs {
100-
if addr.IP.String() == eip.localIP {
101-
_, eip.localEgressNet, err = net.ParseCIDR(addr.IPNet.String())
102-
if err != nil {
103-
return fmt.Errorf("could not parse CIDR network from address %q: %v", addr.IP.String(), err)
104-
}
105-
eip.localEgressLink = link
106-
eip.localEgressIPMaskLen, _ = addr.Mask.Size()
107-
return nil
108-
}
109-
}
110-
}
111-
112-
return fmt.Errorf("could not find network interface with the address %q", eip.localIP)
113-
}
114-
11588
func ipToHex(ip string) string {
11689
bytes := net.ParseIP(ip)
11790
if bytes == nil {
@@ -287,7 +260,8 @@ func (eip *egressIPWatcher) claimEgressIP(egressIP, egressHex string) error {
287260
return nil
288261
}
289262

290-
egressIPNet := fmt.Sprintf("%s/%d", egressIP, eip.localEgressIPMaskLen)
263+
localEgressIPMaskLen, _ := eip.localEgressNet.Mask.Size()
264+
egressIPNet := fmt.Sprintf("%s/%d", egressIP, localEgressIPMaskLen)
291265
addr, err := netlink.ParseAddr(egressIPNet)
292266
if err != nil {
293267
return fmt.Errorf("could not parse egress IP %q: %v", egressIPNet, err)
@@ -321,7 +295,8 @@ func (eip *egressIPWatcher) releaseEgressIP(egressIP, egressHex string) error {
321295
return nil
322296
}
323297

324-
egressIPNet := fmt.Sprintf("%s/%d", egressIP, eip.localEgressIPMaskLen)
298+
localEgressIPMaskLen, _ := eip.localEgressNet.Mask.Size()
299+
egressIPNet := fmt.Sprintf("%s/%d", egressIP, localEgressIPMaskLen)
325300
addr, err := netlink.ParseAddr(egressIPNet)
326301
if err != nil {
327302
return fmt.Errorf("could not parse egress IP %q: %v", egressIPNet, err)

pkg/network/node/node.go

+44-26
Original file line numberDiff line numberDiff line change
@@ -143,37 +143,18 @@ func New(c *OsdnNodeConfig) (network.NodeInterface, error) {
143143
// Not an OpenShift plugin
144144
return nil, nil
145145
}
146+
glog.Infof("Initializing SDN node of type %q with configured hostname %q (IP %q), iptables sync period %q", c.PluginName, c.Hostname, c.SelfIP, c.IPTablesSyncPeriod.String())
147+
148+
if useConnTrack && c.ProxyMode != componentconfig.ProxyModeIPTables {
149+
return nil, fmt.Errorf("%q plugin is not compatible with proxy-mode %q", c.PluginName, c.ProxyMode)
150+
}
146151

147152
// If our CNI config file exists, remove it so that kubelet doesn't think
148153
// we're ready yet
149154
os.Remove(filepath.Join(cniDirPath, openshiftCNIFile))
150155

151-
glog.Infof("Initializing SDN node of type %q with configured hostname %q (IP %q), iptables sync period %q", c.PluginName, c.Hostname, c.SelfIP, c.IPTablesSyncPeriod.String())
152-
if c.Hostname == "" {
153-
output, err := kexec.New().Command("uname", "-n").CombinedOutput()
154-
if err != nil {
155-
return nil, err
156-
}
157-
c.Hostname = strings.TrimSpace(string(output))
158-
glog.Infof("Resolved hostname to %q", c.Hostname)
159-
}
160-
if c.SelfIP == "" {
161-
var err error
162-
c.SelfIP, err = netutils.GetNodeIP(c.Hostname)
163-
if err != nil {
164-
glog.V(5).Infof("Failed to determine node address from hostname %s; using default interface (%v)", c.Hostname, err)
165-
var defaultIP net.IP
166-
defaultIP, err = kubeutilnet.ChooseHostInterface()
167-
if err != nil {
168-
return nil, err
169-
}
170-
c.SelfIP = defaultIP.String()
171-
glog.Infof("Resolved IP address to %q", c.SelfIP)
172-
}
173-
}
174-
175-
if useConnTrack && c.ProxyMode != componentconfig.ProxyModeIPTables {
176-
return nil, fmt.Errorf("%q plugin is not compatible with proxy-mode %q", c.PluginName, c.ProxyMode)
156+
if err := c.setNodeIP(); err != nil {
157+
return nil, err
177158
}
178159

179160
ovsif, err := ovs.New(kexec.New(), Br0, minOvsVersion)
@@ -215,6 +196,43 @@ func New(c *OsdnNodeConfig) (network.NodeInterface, error) {
215196
return plugin, nil
216197
}
217198

199+
// Set node IP if required
200+
func (c *OsdnNodeConfig) setNodeIP() error {
201+
if len(c.Hostname) == 0 {
202+
output, err := kexec.New().Command("uname", "-n").CombinedOutput()
203+
if err != nil {
204+
return err
205+
}
206+
c.Hostname = strings.TrimSpace(string(output))
207+
glog.Infof("Resolved hostname to %q", c.Hostname)
208+
}
209+
210+
if len(c.SelfIP) == 0 {
211+
var err error
212+
c.SelfIP, err = netutils.GetNodeIP(c.Hostname)
213+
if err != nil {
214+
glog.V(5).Infof("Failed to determine node address from hostname %s; using default interface (%v)", c.Hostname, err)
215+
var defaultIP net.IP
216+
defaultIP, err = kubeutilnet.ChooseHostInterface()
217+
if err != nil {
218+
return err
219+
}
220+
c.SelfIP = defaultIP.String()
221+
glog.Infof("Resolved IP address to %q", c.SelfIP)
222+
}
223+
}
224+
225+
if _, _, err := common.GetLinkDetails(c.SelfIP); err != nil {
226+
if err == common.ErrorNetworkInterfaceNotFound {
227+
return fmt.Errorf("node IP %q is not a local/private address (hostname %q)", c.SelfIP, c.Hostname)
228+
} else {
229+
return err
230+
}
231+
}
232+
233+
return nil
234+
}
235+
218236
// Detect whether we are upgrading from a pre-CNI openshift and clean up
219237
// interfaces and iptables rules that are no longer required
220238
func (node *OsdnNode) dockerPreCNICleanup() error {

0 commit comments

Comments
 (0)