func()

in pkg/networkutils/network.go [254:355]


func (n *linuxNetwork) SetupHostNetwork(vpcv4CIDRs []string, primaryMAC string, primaryAddr *net.IP, enablePodENI bool,
	v4Enabled bool, v6Enabled bool) error {
	log.Info("Setting up host network... ")

	var err error
	primaryIntf := "eth0"
	//RP Filter setting is only needed if IPv4 mode is enabled.
	if v4Enabled && n.nodePortSupportEnabled {
		primaryIntf, err = findPrimaryInterfaceName(primaryMAC)
		if err != nil {
			return errors.Wrapf(err, "failed to SetupHostNetwork")
		}
		// If node port support is enabled, configure the kernel's reverse path filter check on eth0 for "loose"
		// filtering. This is required because
		// - NodePorts are exposed on eth0
		// - The kernel's RPF check happens after incoming packets to NodePorts are DNATted to the pod IP.
		// - For pods assigned to secondary ENIs, the routing table includes source-based routing. When the kernel does
		//   the RPF check, it looks up the route using the pod IP as the source.
		// - Thus, it finds the source-based route that leaves via the secondary ENI.
		// - In "strict" mode, the RPF check fails because the return path uses a different interface to the incoming
		//   packet. In "loose" mode, the check passes because some route was found.
		primaryIntfRPFilter := "net/ipv4/conf/" + primaryIntf + "/rp_filter"
		const rpFilterLoose = "2"

		if n.shouldConfigureRpFilter {
			log.Debugf("Setting RPF for primary interface: %s", primaryIntfRPFilter)
			err = n.procSys.Set(primaryIntfRPFilter, rpFilterLoose)
			if err != nil {
				return errors.Wrapf(err, "failed to configure %s RPF check", primaryIntf)
			}
		} else {
			log.Infof("Skip updating RPF for primary interface: %s", primaryIntfRPFilter)
		}
	}

	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 MTU to %d for %s", n.mtu, primaryIntf)
	}

	ipFamily := unix.AF_INET
	if v6Enabled {
		ipFamily = unix.AF_INET6
		if err := n.enableIPv6(); err != nil {
			return errors.Wrapf(err, "failed to enable IPv6")
		}
	}

	// 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 = int(n.mainENIMark)
	mainENIRule.Mask = int(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 {
		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")
		}
	}

	// If we want per pod ENIs, we need to give pod ENIs veth bridges a lower priority that the local table,
	// or the rp_filter check will fail.
	// Note: Per Pod Security Group is not supported for V6 yet. So, cordoning off the PPSG rule (for now)
	// with v4 specific check.
	if v4Enabled && enablePodENI {
		localRule := n.netLink.NewRule()
		localRule.Table = localRouteTable
		localRule.Priority = localRulePriority
		// 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")
		}
	}

	return n.updateHostIptablesRules(vpcv4CIDRs, primaryMAC, primaryAddr, v4Enabled, v6Enabled)
}