func()

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)
}