in cni/network/network.go [725:868]
func (plugin *NetPlugin) createEpInfo(opt *createEpInfoOpt) (*network.EndpointInfo, error) { // you can modify to pass in whatever else you need
// ensure we can find the master interface
opt.ifInfo.HostSubnetPrefix.IP = opt.ifInfo.HostSubnetPrefix.IP.Mask(opt.ifInfo.HostSubnetPrefix.Mask)
opt.ipamAddConfig.nwCfg.IPAM.Subnet = opt.ifInfo.HostSubnetPrefix.String()
// populate endpoint info section
masterIfName := plugin.findMasterInterface(opt)
if masterIfName == "" {
err := plugin.Errorf("Failed to find the master interface")
return nil, err
}
networkPolicies := opt.policies // save network policies before we modify the slice pointer for ep policies
// populate endpoint info
epDNSInfo, err := getEndpointDNSSettings(opt.nwCfg, opt.ifInfo.DNS, opt.k8sNamespace) // Probably won't panic if given bad values
if err != nil {
err = plugin.Errorf("Failed to getEndpointDNSSettings: %v", err)
return nil, err
}
vethName := fmt.Sprintf("%s.%s", opt.k8sNamespace, opt.k8sPodName)
if opt.nwCfg.Mode != OpModeTransparent {
// this mechanism of using only namespace and name is not unique for different incarnations of POD/container.
// IT will result in unpredictable behavior if API server decides to
// reorder DELETE and ADD call for new incarnation of same POD.
vethName = fmt.Sprintf("%s%s%s", opt.networkID, opt.args.ContainerID, opt.args.IfName)
}
// for secondary (Populate addresses)
// initially only for infra nic but now applied to all nic types
addresses := make([]net.IPNet, len(opt.ifInfo.IPConfigs))
for i, ipconfig := range opt.ifInfo.IPConfigs {
addresses[i] = ipconfig.Address
}
// generate endpoint info
var endpointID, ifName string
if opt.ifInfo.NICType == cns.InfraNIC && !*opt.infraSeen {
// so we do not break existing scenarios, only the first infra gets the original endpoint id generation
ifName = opt.args.IfName
endpointID = plugin.nm.GetEndpointID(opt.args.ContainerID, ifName)
*opt.infraSeen = true
} else {
ifName = "eth" + strconv.Itoa(opt.endpointIndex)
endpointID = plugin.nm.GetEndpointID(opt.args.ContainerID, ifName)
}
endpointInfo := network.EndpointInfo{
NetworkID: opt.networkID,
Mode: opt.ipamAddConfig.nwCfg.Mode,
MasterIfName: masterIfName,
AdapterName: opt.ipamAddConfig.nwCfg.AdapterName,
BridgeName: opt.ipamAddConfig.nwCfg.Bridge,
NetworkPolicies: networkPolicies, // nw and ep policies separated to avoid possible conflicts
NetNs: opt.ipamAddConfig.args.Netns,
Options: opt.ipamAddConfig.shallowCopyIpamAddConfigOptions(),
DisableHairpinOnHostInterface: opt.ipamAddConfig.nwCfg.DisableHairpinOnHostInterface,
IsIPv6Enabled: opt.ipv6Enabled, // present infra only
EndpointID: endpointID,
ContainerID: opt.args.ContainerID,
NetNsPath: opt.args.Netns, // probably same value as epInfo.NetNs
IfName: ifName,
Data: make(map[string]interface{}),
EndpointDNS: epDNSInfo,
// endpoint policies are populated later
IPsToRouteViaHost: opt.nwCfg.IPsToRouteViaHost,
EnableSnatOnHost: opt.nwCfg.EnableSnatOnHost,
EnableMultiTenancy: opt.nwCfg.MultiTenancy,
EnableInfraVnet: opt.enableInfraVnet,
EnableSnatForDns: opt.enableSnatForDNS,
PODName: opt.k8sPodName,
PODNameSpace: opt.k8sNamespace,
SkipHotAttachEp: false, // Hot attach at the time of endpoint creation
IPV6Mode: opt.nwCfg.IPV6Mode,
VnetCidrs: opt.nwCfg.VnetCidrs,
ServiceCidrs: opt.nwCfg.ServiceCidrs,
NATInfo: opt.natInfo,
NICType: opt.ifInfo.NICType,
SkipDefaultRoutes: opt.ifInfo.SkipDefaultRoutes,
Routes: opt.ifInfo.Routes,
// added the following for delegated vm nic
IPAddresses: addresses,
MacAddress: opt.ifInfo.MacAddress,
// the following is used for creating an external interface if we can't find an existing network
HostSubnetPrefix: opt.ifInfo.HostSubnetPrefix.String(),
PnPID: opt.ifInfo.PnPID,
}
if err = addSubnetToEndpointInfo(*opt.ifInfo, &endpointInfo); err != nil {
logger.Info("Failed to add subnets to endpointInfo", zap.Error(err))
return nil, err
}
setNetworkOptions(opt.ifInfo.NCResponse, &endpointInfo)
// update endpoint policies
policyArgs := PolicyArgs{
subnetInfos: endpointInfo.Subnets, // getEndpointPolicies requires nwInfo.Subnets only (checked)
nwCfg: opt.nwCfg,
ipconfigs: opt.ifInfo.IPConfigs,
}
endpointPolicies, err := getEndpointPolicies(policyArgs)
if err != nil {
logger.Error("Failed to get endpoint policies", zap.Error(err))
return nil, err
}
// create endpoint policies by appending to network policies
// the value passed into NetworkPolicies should be unaffected since we reassign here
opt.policies = append(opt.policies, endpointPolicies...)
// appends endpoint policies specific to this interface
opt.policies = append(opt.policies, opt.ifInfo.EndpointPolicies...)
endpointInfo.EndpointPolicies = opt.policies
// add even more endpoint policies
epPolicies, err := getPoliciesFromRuntimeCfg(opt.nwCfg, opt.ipamAddResult.ipv6Enabled) // not specific to delegated or infra
if err != nil {
logger.Error("failed to get policies from runtime configurations", zap.Error(err))
return nil, plugin.Errorf(err.Error())
}
endpointInfo.EndpointPolicies = append(endpointInfo.EndpointPolicies, epPolicies...)
if opt.ipamAddResult.ipv6Enabled { // not specific to this particular interface
endpointInfo.IPV6Mode = string(util.IpamMode(opt.nwCfg.IPAM.Mode)) // TODO: check IPV6Mode field can be deprecated and can we add IsIPv6Enabled flag for generic working
}
if opt.azIpamResult != nil && opt.azIpamResult.IPs != nil {
endpointInfo.InfraVnetIP = opt.azIpamResult.IPs[0].Address
}
if opt.nwCfg.MultiTenancy {
// previously only infra nic was passed into this function but now all nics are passed in (possibly breaks swift v2)
plugin.multitenancyClient.SetupRoutingForMultitenancy(opt.nwCfg, opt.cnsNetworkConfig, opt.azIpamResult, &endpointInfo, opt.ifInfo)
}
setEndpointOptions(opt.cnsNetworkConfig, &endpointInfo, vethName)
logger.Info("Generated endpoint info from fields", zap.String("epInfo", endpointInfo.PrettyString()))
// now our ep info should have the full combined information from both the network and endpoint structs
return &endpointInfo, nil
}