func translateEgress()

in npm/pkg/controlplane/controllers/v1/translatePolicy.go [880:1535]


func translateEgress(ns string, policyName string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, map[string][]string, [][]string, []*iptm.IptEntry) {
	var (
		netHashIPsets  []string            // ipsets with type: net:hash
		namedPorts     []string            // ipsets with type: hash:ip,port
		listIPsets     map[string][]string // ipsets with type: list:set
		ipCidrs        [][]string
		entries        []*iptm.IptEntry
		toRuleEntries  []*iptm.IptEntry
		addedCidrEntry bool // all cidr entry will be added in one set per from/to rule
		addedPortEntry bool // add drop entry when there are non ALLOW-ALL* rules
	)

	log.Logf("started parsing egress rule")
	netHashIPsets = append(netHashIPsets, "ns-"+ns)
	ipCidrs = make([][]string, len(rules))
	listIPsets = make(map[string][]string)

	targetSelectorIptEntrySpec, labels, listLabelsWithMembers := craftPartialIptEntrySpecFromSelector(ns, &targetSelector, util.IptablesSrcFlag, false)
	netHashIPsets = append(netHashIPsets, labels...)
	appendSelectorLabelsToLists(listIPsets, listLabelsWithMembers, false)
	targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false)
	for i, rule := range rules {
		allowExternal := false
		portRuleExists := rule.Ports != nil && len(rule.Ports) > 0
		toRuleExists := false
		addedPortEntry = addedPortEntry || portRuleExists
		ipCidrs[i] = make([]string, len(rule.To))

		if rule.To != nil {
			if len(rule.To) == 0 {
				toRuleExists = true
				allowExternal = true
			}

			for _, toRule := range rule.To {
				if toRule.PodSelector != nil ||
					toRule.NamespaceSelector != nil ||
					toRule.IPBlock != nil {
					toRuleExists = true
					break
				}
			}
		} else if !portRuleExists {
			allowExternal = true
		}

		if !portRuleExists && !toRuleExists && !allowExternal {
			entry := &iptm.IptEntry{
				Chain: util.IptablesAzureEgressPortChain,
				Specs: append([]string(nil), targetSelectorIptEntrySpec...),
			}
			entry.Specs = append(
				entry.Specs,
				util.IptablesModuleFlag,
				util.IptablesSetModuleFlag,
				util.IptablesMatchSetFlag,
				util.GetHashedName(util.KubeAllNamespacesFlag),
				util.IptablesDstFlag,
				util.IptablesJumpFlag,
				util.IptablesMark,
				util.IptablesSetMarkFlag,
				util.IptablesAzureEgressXMarkHex,
				util.IptablesModuleFlag,
				util.IptablesCommentModuleFlag,
				util.IptablesCommentFlag,
				"ALLOW-ALL-FROM-"+targetSelectorComment+
					"-TO-"+util.KubeAllNamespacesFlag,
			)

			entries = append(entries, entry)
			if _, ok := listIPsets[util.KubeAllNamespacesFlag]; !ok {
				listIPsets[util.KubeAllNamespacesFlag] = nil
			}
			continue
		}

		// Only Ports rules exist
		if portRuleExists && !toRuleExists && !allowExternal {
			for _, portRule := range rule.Ports {
				switch portCheck := getPortType(portRule); portCheck {
				case "namedport":
					portName := util.NamedPortIPSetPrefix + portRule.Port.String()
					namedPorts = append(namedPorts, portName)
					entry := &iptm.IptEntry{
						Chain: util.IptablesAzureEgressPortChain,
						Specs: append([]string(nil), targetSelectorIptEntrySpec...),
					}
					if portRule.Protocol != nil {
						entry.Specs = append(
							entry.Specs,
							util.IptablesProtFlag,
							string(*portRule.Protocol),
						)
					}
					entry.Specs = append(
						entry.Specs,
						util.IptablesModuleFlag,
						util.IptablesSetModuleFlag,
						util.IptablesMatchSetFlag,
						util.GetHashedName(portName),
						util.IptablesDstFlag+","+util.IptablesDstFlag,
						util.IptablesJumpFlag,
						util.IptablesMark,
						util.IptablesSetMarkFlag,
						util.IptablesAzureEgressXMarkHex,
						util.IptablesModuleFlag,
						util.IptablesCommentModuleFlag,
						util.IptablesCommentFlag,
						"ALLOW-ALL-TO-"+
							craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
							"-FROM-"+targetSelectorComment,
					)
					entries = append(entries, entry)
				case "validport":
					entry := &iptm.IptEntry{
						Chain: util.IptablesAzureEgressPortChain,
						Specs: craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag),
					}
					entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...)
					entry.Specs = append(
						entry.Specs,
						util.IptablesJumpFlag,
						util.IptablesMark,
						util.IptablesSetMarkFlag,
						util.IptablesAzureEgressXMarkHex,
						util.IptablesModuleFlag,
						util.IptablesCommentModuleFlag,
						util.IptablesCommentFlag,
						"ALLOW-ALL-TO-"+
							craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
							"-FROM-"+targetSelectorComment,
					)
					entries = append(entries, entry)
				default:
					log.Logf("Invalid NetworkPolicyPort.")
				}
			}
			continue
		}

		// toRuleExists
		for j, toRule := range rule.To {
			// Handle IPBlock field of NetworkPolicyPeer
			if toRule.IPBlock != nil {
				if len(toRule.IPBlock.CIDR) > 0 {
					ipCidrs[i] = append(ipCidrs[i], toRule.IPBlock.CIDR)
					cidrIpsetName := policyName + "-in-ns-" + ns + "-" + strconv.Itoa(i) + "out"
					if len(toRule.IPBlock.Except) > 0 {
						for _, except := range toRule.IPBlock.Except {
							// TODO move IP cidrs rule to allow based only
							ipCidrs[i] = append(ipCidrs[i], except+util.IpsetNomatch)
						}
					}
					if j != 0 && addedCidrEntry {
						continue
					}
					if portRuleExists {
						for _, portRule := range rule.Ports {
							switch portCheck := getPortType(portRule); portCheck {
							case "namedport":
								portName := util.NamedPortIPSetPrefix + portRule.Port.String()
								namedPorts = append(namedPorts, portName)
								entry := &iptm.IptEntry{
									Chain: util.IptablesAzureEgressPortChain,
									Specs: append([]string(nil), targetSelectorIptEntrySpec...),
								}
								if portRule.Protocol != nil {
									entry.Specs = append(
										entry.Specs,
										util.IptablesProtFlag,
										string(*portRule.Protocol),
									)
								}
								entry.Specs = append(
									entry.Specs,
									util.IptablesModuleFlag,
									util.IptablesSetModuleFlag,
									util.IptablesMatchSetFlag,
									util.GetHashedName(cidrIpsetName),
									util.IptablesDstFlag,
								)
								entry.Specs = append(
									entry.Specs,
									util.IptablesModuleFlag,
									util.IptablesSetModuleFlag,
									util.IptablesMatchSetFlag,
									util.GetHashedName(portName),
									util.IptablesDstFlag+","+util.IptablesDstFlag,
									util.IptablesJumpFlag,
									util.IptablesMark,
									util.IptablesSetMarkFlag,
									util.IptablesAzureEgressXMarkHex,
									util.IptablesModuleFlag,
									util.IptablesCommentModuleFlag,
									util.IptablesCommentFlag,
									"ALLOW-"+cidrIpsetName+
										"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
										"-FROM-"+targetSelectorComment,
								)
								toRuleEntries = append(toRuleEntries, entry)
							case "validport":
								entry := &iptm.IptEntry{
									Chain: util.IptablesAzureEgressPortChain,
									Specs: craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag),
								}
								entry.Specs = append(
									entry.Specs,
									targetSelectorIptEntrySpec...,
								)
								entry.Specs = append(
									entry.Specs,
									util.IptablesModuleFlag,
									util.IptablesSetModuleFlag,
									util.IptablesMatchSetFlag,
									util.GetHashedName(cidrIpsetName),
									util.IptablesDstFlag,
								)
								entry.Specs = append(
									entry.Specs,
									util.IptablesJumpFlag,
									util.IptablesMark,
									util.IptablesSetMarkFlag,
									util.IptablesAzureEgressXMarkHex,
									util.IptablesModuleFlag,
									util.IptablesCommentModuleFlag,
									util.IptablesCommentFlag,
									"ALLOW-"+cidrIpsetName+
										"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
										"-FROM-"+targetSelectorComment,
								)
								toRuleEntries = append(toRuleEntries, entry)
							default:
								log.Logf("Invalid NetworkPolicyPort.")
							}
						}
					} else {
						entry := &iptm.IptEntry{
							Chain: util.IptablesAzureEgressToChain,
						}
						entry.Specs = append(
							entry.Specs,
							targetSelectorIptEntrySpec...,
						)
						entry.Specs = append(
							entry.Specs,
							util.IptablesModuleFlag,
							util.IptablesSetModuleFlag,
							util.IptablesMatchSetFlag,
							util.GetHashedName(cidrIpsetName),
							util.IptablesDstFlag,
						)
						entry.Specs = append(
							entry.Specs,
							util.IptablesJumpFlag,
							util.IptablesMark,
							util.IptablesSetMarkFlag,
							util.IptablesAzureEgressXMarkHex,
							util.IptablesModuleFlag,
							util.IptablesCommentModuleFlag,
							util.IptablesCommentFlag,
							"ALLOW-"+cidrIpsetName+
								"-FROM-"+targetSelectorComment,
						)
						toRuleEntries = append(toRuleEntries, entry)
					}
					addedCidrEntry = true
				}
				continue
			}

			// Handle podSelector and namespaceSelector.
			// For PodSelector, use hash:net in ipset.
			// For NamespaceSelector, use set:list in ipset.
			if toRule.PodSelector == nil && toRule.NamespaceSelector == nil {
				continue
			}

			if toRule.PodSelector == nil && toRule.NamespaceSelector != nil {
				for _, nsSelector := range FlattenNameSpaceSelector(toRule.NamespaceSelector) {
					iptPartialNsSpec, nsLabelsWithoutOps, listLabelsWithMembers := craftPartialIptEntrySpecFromSelector("", &nsSelector, util.IptablesDstFlag, true)
					if len(nsLabelsWithoutOps) == 1 && nsLabelsWithoutOps[0] == "" {
						// Empty namespaceSelector. This selects all namespaces
						nsLabelsWithoutOps[0] = util.KubeAllNamespacesFlag
						if _, ok := listIPsets[nsLabelsWithoutOps[0]]; !ok {
							listIPsets[nsLabelsWithoutOps[0]] = nil
						}
					} else {
						for i := range nsLabelsWithoutOps {
							// Add namespaces prefix to distinguish namespace ipset lists and pod ipsets
							nsLabelsWithoutOps[i] = util.GetNSNameWithPrefix(nsLabelsWithoutOps[i])
							if _, ok := listIPsets[nsLabelsWithoutOps[i]]; !ok {
								listIPsets[nsLabelsWithoutOps[i]] = nil
							}
						}
						appendSelectorLabelsToLists(listIPsets, listLabelsWithMembers, true)
					}
					iptPartialNsComment := craftPartialIptablesCommentFromSelector("", &nsSelector, true)
					if portRuleExists {
						for _, portRule := range rule.Ports {
							switch portCheck := getPortType(portRule); portCheck {
							case "namedport":
								portName := util.NamedPortIPSetPrefix + portRule.Port.String()
								namedPorts = append(namedPorts, portName)
								entry := &iptm.IptEntry{
									Chain: util.IptablesAzureEgressPortChain,
									Specs: append([]string(nil), iptPartialNsSpec...),
								}
								entry.Specs = append(
									entry.Specs,
									targetSelectorIptEntrySpec...,
								)
								entry.Specs = append(
									entry.Specs,
									util.IptablesModuleFlag,
									util.IptablesSetModuleFlag,
									util.IptablesMatchSetFlag,
									util.GetHashedName(portName),
									util.IptablesDstFlag+","+util.IptablesDstFlag,
									util.IptablesJumpFlag,
									util.IptablesMark,
									util.IptablesSetMarkFlag,
									util.IptablesAzureEgressXMarkHex,
									util.IptablesModuleFlag,
									util.IptablesCommentModuleFlag,
									util.IptablesCommentFlag,
									"ALLOW-"+iptPartialNsComment+
										"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
										"-FROM-"+targetSelectorComment,
								)
								entries = append(entries, entry)
							case "validport":
								entry := &iptm.IptEntry{
									Chain: util.IptablesAzureEgressPortChain,
									Specs: append([]string(nil), iptPartialNsSpec...),
								}
								entry.Specs = append(
									entry.Specs,
									craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag)...,
								)
								entry.Specs = append(
									entry.Specs,
									targetSelectorIptEntrySpec...,
								)
								entry.Specs = append(
									entry.Specs,
									util.IptablesJumpFlag,
									util.IptablesMark,
									util.IptablesSetMarkFlag,
									util.IptablesAzureEgressXMarkHex,
									util.IptablesModuleFlag,
									util.IptablesCommentModuleFlag,
									util.IptablesCommentFlag,
									"ALLOW-"+iptPartialNsComment+
										"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
										"-FROM-"+targetSelectorComment,
								)
								entries = append(entries, entry)
							default:
								log.Logf("Invalid NetworkPolicyPort.")
							}
						}
					} else {
						entry := &iptm.IptEntry{
							Chain: util.IptablesAzureEgressToChain,
							Specs: append([]string(nil), targetSelectorIptEntrySpec...),
						}
						entry.Specs = append(
							entry.Specs,
							iptPartialNsSpec...,
						)
						entry.Specs = append(
							entry.Specs,
							util.IptablesJumpFlag,
							util.IptablesMark,
							util.IptablesSetMarkFlag,
							util.IptablesAzureEgressXMarkHex,
							util.IptablesModuleFlag,
							util.IptablesCommentModuleFlag,
							util.IptablesCommentFlag,
							"ALLOW-"+targetSelectorComment+
								"-TO-"+iptPartialNsComment,
						)
						entries = append(entries, entry)
					}
				}
				continue
			}

			if toRule.PodSelector != nil && toRule.NamespaceSelector == nil {
				iptPartialPodSpec, podLabelsWithoutOps, listPodLabelsWithMembers := craftPartialIptEntrySpecFromSelector(ns, toRule.PodSelector, util.IptablesDstFlag, false)
				if len(podLabelsWithoutOps) == 1 {
					if podLabelsWithoutOps[0] == "" {
						podLabelsWithoutOps[0] = util.GetNSNameWithPrefix(ns)
					}
				}
				netHashIPsets = append(netHashIPsets, podLabelsWithoutOps...)
				// TODO check if the ns- is needed here ?
				appendSelectorLabelsToLists(listIPsets, listPodLabelsWithMembers, false)
				iptPartialPodComment := craftPartialIptablesCommentFromSelector(ns, toRule.PodSelector, false)
				if portRuleExists {
					for _, portRule := range rule.Ports {
						switch portCheck := getPortType(portRule); portCheck {
						case "namedport":
							portName := util.NamedPortIPSetPrefix + portRule.Port.String()
							namedPorts = append(namedPorts, portName)
							entry := &iptm.IptEntry{
								Chain: util.IptablesAzureEgressPortChain,
								Specs: append([]string(nil), iptPartialPodSpec...),
							}
							entry.Specs = append(
								entry.Specs,
								targetSelectorIptEntrySpec...,
							)
							if portRule.Protocol != nil {
								entry.Specs = append(
									entry.Specs,
									util.IptablesProtFlag,
									string(*portRule.Protocol),
								)
							}
							entry.Specs = append(
								entry.Specs,
								util.IptablesModuleFlag,
								util.IptablesSetModuleFlag,
								util.IptablesMatchSetFlag,
								util.GetHashedName(portName),
								util.IptablesDstFlag+","+util.IptablesDstFlag,
								util.IptablesJumpFlag,
								util.IptablesMark,
								util.IptablesSetMarkFlag,
								util.IptablesAzureEgressXMarkHex,
								util.IptablesModuleFlag,
								util.IptablesCommentModuleFlag,
								util.IptablesCommentFlag,
								"ALLOW-"+iptPartialPodComment+
									"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
									"-FROM-"+targetSelectorComment,
							)
							entries = append(entries, entry)
						case "validport":
							entry := &iptm.IptEntry{
								Chain: util.IptablesAzureEgressPortChain,
								Specs: append([]string(nil), iptPartialPodSpec...),
							}
							entry.Specs = append(
								entry.Specs,
								craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag)...,
							)
							entry.Specs = append(
								entry.Specs,
								targetSelectorIptEntrySpec...,
							)
							entry.Specs = append(
								entry.Specs,
								util.IptablesJumpFlag,
								util.IptablesMark,
								util.IptablesSetMarkFlag,
								util.IptablesAzureEgressXMarkHex,
								util.IptablesModuleFlag,
								util.IptablesCommentModuleFlag,
								util.IptablesCommentFlag,
								"ALLOW-"+iptPartialPodComment+
									"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag)+
									"-FROM-"+targetSelectorComment,
							)
							entries = append(entries, entry)
						default:
							log.Logf("Invalid NetworkPolicyPort.")
						}
					}
				} else {
					entry := &iptm.IptEntry{
						Chain: util.IptablesAzureEgressToChain,
						Specs: append([]string(nil), targetSelectorIptEntrySpec...),
					}
					entry.Specs = append(
						entry.Specs,
						iptPartialPodSpec...,
					)
					entry.Specs = append(
						entry.Specs,
						util.IptablesJumpFlag,
						util.IptablesMark,
						util.IptablesSetMarkFlag,
						util.IptablesAzureEgressXMarkHex,
						util.IptablesModuleFlag,
						util.IptablesCommentModuleFlag,
						util.IptablesCommentFlag,
						"ALLOW-"+targetSelectorComment+
							"-TO-"+iptPartialPodComment,
					)
					entries = append(entries, entry)
				}
				continue
			}

			for _, nsSelector := range FlattenNameSpaceSelector(toRule.NamespaceSelector) {
				// we pass true for the podspec and comment here because it's a combo of both selectors and not limited to network policy namespace
				iptPartialNsSpec, nsLabelsWithoutOps, listLabelsWithMembers := craftPartialIptEntrySpecFromSelector("", &nsSelector, util.IptablesDstFlag, true)
				// Add namespaces prefix to distinguish namespace ipsets and pod ipsets
				for i := range nsLabelsWithoutOps {
					nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i]
					if _, ok := listIPsets[nsLabelsWithoutOps[i]]; !ok {
						listIPsets[nsLabelsWithoutOps[i]] = nil
					}
				}
				appendSelectorLabelsToLists(listIPsets, listLabelsWithMembers, true)
				iptPartialPodSpec, podLabelsWithoutOps, listPodLabelsWithMembers := craftPartialIptEntrySpecFromSelector("", toRule.PodSelector, util.IptablesDstFlag, false)
				netHashIPsets = append(netHashIPsets, podLabelsWithoutOps...)
				appendSelectorLabelsToLists(listIPsets, listPodLabelsWithMembers, false)
				iptPartialNsComment := craftPartialIptablesCommentFromSelector("", &nsSelector, true)
				iptPartialPodComment := craftPartialIptablesCommentFromSelector("", toRule.PodSelector, false)
				if portRuleExists {
					for _, portRule := range rule.Ports {
						switch portCheck := getPortType(portRule); portCheck {
						case "namedport":
							portName := util.NamedPortIPSetPrefix + portRule.Port.String()
							namedPorts = append(namedPorts, portName)
							entry := &iptm.IptEntry{
								Chain: util.IptablesAzureEgressPortChain,
								Specs: append([]string(nil), targetSelectorIptEntrySpec...),
							}
							entry.Specs = append(
								entry.Specs,
								iptPartialNsSpec...,
							)
							entry.Specs = append(
								entry.Specs,
								iptPartialPodSpec...,
							)
							if portRule.Protocol != nil {
								entry.Specs = append(
									entry.Specs,
									util.IptablesProtFlag,
									string(*portRule.Protocol),
								)
							}
							entry.Specs = append(
								entry.Specs,
								util.IptablesModuleFlag,
								util.IptablesSetModuleFlag,
								util.IptablesMatchSetFlag,
								util.GetHashedName(portName),
								util.IptablesDstFlag+","+util.IptablesDstFlag,
								util.IptablesJumpFlag,
								util.IptablesMark,
								util.IptablesSetMarkFlag,
								util.IptablesAzureEgressXMarkHex,
								util.IptablesModuleFlag,
								util.IptablesCommentModuleFlag,
								util.IptablesCommentFlag,
								"ALLOW-"+targetSelectorComment+
									"-TO-"+iptPartialNsComment+
									"-AND-"+iptPartialPodComment+
									"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag),
							)
							entries = append(entries, entry)
						case "validport":
							entry := &iptm.IptEntry{
								Chain: util.IptablesAzureEgressPortChain,
								Specs: append([]string(nil), targetSelectorIptEntrySpec...),
							}
							entry.Specs = append(
								entry.Specs,
								iptPartialNsSpec...,
							)
							entry.Specs = append(
								entry.Specs,
								iptPartialPodSpec...,
							)
							entry.Specs = append(
								entry.Specs,
								craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag)...,
							)
							entry.Specs = append(
								entry.Specs,
								util.IptablesJumpFlag,
								util.IptablesMark,
								util.IptablesSetMarkFlag,
								util.IptablesAzureEgressXMarkHex,
								util.IptablesModuleFlag,
								util.IptablesCommentModuleFlag,
								util.IptablesCommentFlag,
								"ALLOW-"+targetSelectorComment+
									"-TO-"+iptPartialNsComment+
									"-AND-"+iptPartialPodComment+
									"-AND-"+craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag),
							)
							entries = append(entries, entry)
						default:
							log.Logf("Invalid NetworkPolicyPort.")
						}
					}
				} else {
					entry := &iptm.IptEntry{
						Chain: util.IptablesAzureEgressToChain,
						Specs: append([]string(nil), targetSelectorIptEntrySpec...),
					}
					entry.Specs = append(
						entry.Specs,
						iptPartialNsSpec...,
					)
					entry.Specs = append(
						entry.Specs,
						iptPartialPodSpec...,
					)
					entry.Specs = append(
						entry.Specs,
						util.IptablesJumpFlag,
						util.IptablesMark,
						util.IptablesSetMarkFlag,
						util.IptablesAzureEgressXMarkHex,
						util.IptablesModuleFlag,
						util.IptablesCommentModuleFlag,
						util.IptablesCommentFlag,
						"ALLOW-"+targetSelectorComment+
							"-TO-"+iptPartialNsComment+
							"-AND-"+iptPartialPodComment,
					)
					entries = append(entries, entry)
				}
			}
		}

		if allowExternal {
			entry := &iptm.IptEntry{
				Chain: util.IptablesAzureEgressPortChain,
				Specs: append([]string(nil), targetSelectorIptEntrySpec...),
			}
			entry.Specs = append(
				entry.Specs,
				util.IptablesJumpFlag,
				util.IptablesMark,
				util.IptablesSetMarkFlag,
				util.IptablesAzureEgressXMarkHex,
				util.IptablesModuleFlag,
				util.IptablesCommentModuleFlag,
				util.IptablesCommentFlag,
				"ALLOW-ALL-FROM-"+
					targetSelectorComment,
			)
			entries = append(entries, entry)
			// borrowing this var to add jump entry from port chain only
			addedPortEntry = true
		}
	}

	// prepending toRuleEntries (which is in reverse order) so that they will retain correct ordering
	// of drop->allow... when the rules are beind prepended to their corresponding chain
	if len(toRuleEntries) > 0 {
		entries = append(toRuleEntries, entries...)
	}

	log.Logf("finished parsing egress rule")
	return util.DropEmptyFields(netHashIPsets), util.DropEmptyFields(namedPorts), listIPsets, ipCidrs, entries
}