Skip to content

Commit bfb1fd9

Browse files
authored
Merge pull request #258 from mars1024/release-0.3
[CHERRY PICK] Prevent enhanced addresses from source selection
2 parents 91dbf6f + ffd187b commit bfb1fd9

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

pkg/daemon/addr/addr.go

+31-1
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ import (
2323
networkingv1 "github.com/alibaba/hybridnet/pkg/apis/networking/v1"
2424
"github.com/alibaba/hybridnet/pkg/daemon/containernetwork"
2525

26-
"github.com/alibaba/hybridnet/pkg/constants"
2726
"github.com/containernetworking/plugins/pkg/ip"
2827
"github.com/vishvananda/netlink"
2928
"golang.org/x/sys/unix"
29+
30+
"github.com/alibaba/hybridnet/pkg/constants"
3031
)
3132

3233
type subnetToPodMap map[string]net.IP
@@ -189,13 +190,42 @@ func (m *Manager) SyncAddresses(getIPInstanceByAddress func(net.IP) (*networking
189190
return fmt.Errorf("parse subnet cidr %v failed: %v", subnetString, err)
190191
}
191192

193+
// ARP sender IP selection is totally independent with IP source selection. ARP sender IP
194+
// selection will only be controlled by arp_announce sysctl parameter.
195+
//
196+
// There are two kinds of results for sender IP selection on a interface with more than one ip address:
197+
// 1. Use source address in the IP header (always fit for us)
198+
// 2. Use the "inet_select_addr" function
199+
//
200+
// For the second possibility, kernel will use the "inet_select_addr" function with a "link" scope
201+
// to select sender IP. That means the first address that matches the subnet of the target IP (of ARP header)
202+
// and has a scope greater than or equal to RT_SCOPE_LINK will be selected.
203+
//
204+
// If a route does not have src specified then:
205+
// 1. ip with scope=host can be as backend only for a route with scope=host
206+
// 2. ip with scope=link can be as backend only for a route with scope=host or scope=link
207+
// 3. ip with scope=global can be as backend only for a route with any scope
208+
//
209+
// As for the IP source selection after routing, if egress interface of the routing result doesn't have any
210+
// address and need to select from other interfaces, only the addresses with "global" scope will be selected.
211+
// So the enhanced address will never be used as source address for other interfaces.
212+
//
213+
// So does the ARP sender IP selection happens on a interface without any address, only the addresses of
214+
// other interfaces with "global" scope will be selected as sender IP. If no valid sender IP found, it will
215+
// be "0.0.0.0".
216+
//
217+
// At the same time, subnet direct routes (scope lower than or equal to "link"), which match hybridnet
218+
// underlay vlan subnets, are never supposed to be added to enhanced-address-attached interfaces directly by
219+
// host. Because of that, we can make the enhanced addresses never be selected as source IP by creating them
220+
// with a "link" scope.
192221
if err := ensureSubnetEnhancedAddr(forwardNodeIf, &netlink.Addr{
193222
IPNet: &net.IPNet{
194223
IP: podIP,
195224
Mask: subnetCidr.Mask,
196225
},
197226
Label: "",
198227
Flags: unix.IFA_F_NOPREFIXROUTE,
228+
Scope: unix.RT_SCOPE_LINK,
199229
}, outOfDateEnhancedAddr, m.family); err != nil {
200230
return fmt.Errorf("ensure subnet enhanced addr %v failed: %v", podIP.String(), err)
201231
}

pkg/daemon/config/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func ParseFlags() (*Configuration, error) {
119119
argNeighGCThresh2 = pflag.Int("neigh-gc-thresh2", DefaultNeighGCThresh2, "Value to set net.ipv4/ipv6.neigh.default.gc_thresh2")
120120
argNeighGCThresh3 = pflag.Int("neigh-gc-thresh3", DefaultNeighGCThresh3, "Value to set net.ipv4/ipv6.neigh.default.gc_thresh3")
121121
argExtraNodeLocalVxlanIPCidrs = pflag.String("extra-node-local-vxlan-ip-cidrs", "", "Cidrs to select node extra local vxlan ip, e.g., \"192.168.10.0/24,10.2.3.0/24\"")
122-
argEnableVlanArpEnhancement = pflag.Bool("enable-vlan-arp-enhancement", false, "Whether enable arp source enhancement in a vlan environment")
122+
argEnableVlanArpEnhancement = pflag.Bool("enable-vlan-arp-enhancement", true, "Whether enable arp source enhancement in a vlan environment")
123123
)
124124

125125
// mute info log for ipset lib

pkg/daemon/controller/ipinstance.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,10 @@ func (c *Controller) reconcileIPInfo() error {
167167
}
168168

169169
if ipInstance.Spec.Address.Version == networkingv1.IPv4 {
170-
c.addrV4Manager.TryAddPodInfo(forwardNodeIfName, subnetCidr, podIP)
170+
// if vlan arp enhancement is not enabled, all the enhanced address will be cleaned
171+
if c.config.EnableVlanArpEnhancement {
172+
c.addrV4Manager.TryAddPodInfo(forwardNodeIfName, subnetCidr, podIP)
173+
}
171174
}
172175

173176
case networkingv1.NetworkTypeOverlay:
@@ -203,10 +206,8 @@ func (c *Controller) reconcileIPInfo() error {
203206
}
204207
}
205208

206-
if c.config.EnableVlanArpEnhancement {
207-
if err := c.addrV4Manager.SyncAddresses(c.getIPInstanceByAddress); err != nil {
208-
return fmt.Errorf("sync ipv4 addresses failed: %v", err)
209-
}
209+
if err := c.addrV4Manager.SyncAddresses(c.getIPInstanceByAddress); err != nil {
210+
return fmt.Errorf("sync ipv4 addresses failed: %v", err)
210211
}
211212

212213
return nil

0 commit comments

Comments
 (0)