in pkg/networkutils/network.go [290:370]
func (n *linuxNetwork) SetupHostNetwork(vpcv4CIDRs []string, primaryMAC string, primaryAddr *net.IP, enablePodENI bool,
v4Enabled bool, v6Enabled bool) error {
log.Info("Setting up host network... ")
link, err := linkByMac(primaryMAC, n.netLink, retryLinkByMacInterval)
if err != nil {
return errors.Wrapf(err, "setupHostNetwork: failed to find the link primary ENI with MAC address %s", primaryMAC)
}
if err = n.netLink.LinkSetMTU(link, n.mtu); err != nil {
return errors.Wrapf(err, "setupHostNetwork: failed to set primary interface MTU to %d", n.mtu)
}
ipFamily := unix.AF_INET
if v6Enabled {
ipFamily = unix.AF_INET6
if err := n.enableIPv6(); err != nil {
return errors.Wrapf(err, "failed to enable IPv6")
}
} else if n.ipv6EgressEnabled {
if err := n.setupRuleToBlockNodeLocalAccess(iptables.ProtocolIPv6); err != nil {
return errors.Wrapf(err, "failed to block node local v6 access")
}
}
// If node port support is enabled, add a rule that will force force marked traffic out of the main ENI. We then
// add iptables rules below that will mark traffic that needs this special treatment. In particular NodePort
// traffic always comes in via the main ENI but response traffic would go out of the pod's assigned ENI if we
// didn't handle it specially. This is because the routing decision is done before the NodePort's DNAT is
// reversed so, to the routing table, it looks like the traffic is pod traffic instead of NodePort traffic.
// Note: With v6 PD mode support, all the pods will be behind Primary ENI of the node and so we might not even need
// to mark the packets entering via Primary ENI for NodePort support.
mainENIRule := n.netLink.NewRule()
mainENIRule.Mark = n.mainENIMark
mainENIRule.Mask = &n.mainENIMark
mainENIRule.Table = mainRoutingTable
mainENIRule.Priority = hostRulePriority
mainENIRule.Family = ipFamily
// If this is a restart, cleanup previous rule first
err = n.netLink.RuleDel(mainENIRule)
if err != nil && !containsNoSuchRule(err) {
log.Errorf("Failed to cleanup old main ENI rule: %v", err)
return errors.Wrapf(err, "host network setup: failed to delete old main ENI rule")
}
if n.nodePortSupportEnabled || !n.useExternalSNAT {
err = n.netLink.RuleAdd(mainENIRule)
if err != nil {
log.Errorf("Failed to add host main ENI rule: %v", err)
return errors.Wrapf(err, "host network setup: failed to add main ENI rule")
}
}
// In strict mode, packets egressing pod veth interfaces must route via the trunk ENI in order for security group
// rules to be applied. Therefore, the rule to lookup the local routing table is moved to a lower priority than VLAN rules.
if enablePodENI && n.podSGEnforcingMode == sgpp.EnforcingModeStrict {
localRule := n.netLink.NewRule()
localRule.Table = localRouteTable
localRule.Priority = localRulePriority
localRule.Family = ipFamily
// Add new rule with higher priority
err := n.netLink.RuleAdd(localRule)
if err != nil && !isRuleExistsError(err) {
return errors.Wrap(err, "ChangeLocalRulePriority: unable to update local rule priority")
}
// Delete the priority 0 rule
localRule.Priority = 0
err = n.netLink.RuleDel(localRule)
if err != nil && !containsNoSuchRule(err) {
return errors.Wrap(err, "ChangeLocalRulePriority: failed to delete priority 0 local rule")
}
// In IPv6 strict mode, ICMPv6 packets from the gateway must lookup in the local routing table so that branch interfaces can resolve their gateway.
if v6Enabled {
if err := n.createIPv6GatewayRule(); err != nil {
return errors.Wrapf(err, "failed to install IPv6 gateway rule")
}
}
}
return n.updateHostIptablesRules(vpcv4CIDRs, primaryMAC, primaryAddr, v4Enabled, v6Enabled)
}