in network/endpoint_windows.go [172:265]
func (nw *network) newEndpointImplHnsV1(epInfo *EndpointInfo, plc platform.ExecClient) (*endpoint, error) {
var vlanid int
if epInfo.Data != nil {
if _, ok := epInfo.Data[VlanIDKey]; ok {
vlanid = epInfo.Data[VlanIDKey].(int)
}
}
// Get Infrastructure containerID. Handle ADD calls for workload container.
var err error
infraEpName, _ := ConstructEndpointID(epInfo.ContainerID, epInfo.NetNsPath, epInfo.IfName)
hnsEndpoint := &hcsshim.HNSEndpoint{
Name: infraEpName,
VirtualNetwork: nw.HnsId,
DNSSuffix: epInfo.EndpointDNS.Suffix,
DNSServerList: strings.Join(epInfo.EndpointDNS.Servers, ","),
Policies: policy.SerializePolicies(policy.EndpointPolicy, epInfo.EndpointPolicies, epInfo.Data, epInfo.EnableSnatForDns, epInfo.EnableMultiTenancy),
}
// HNS currently supports one IP address and one IPv6 address per endpoint.
for _, ipAddr := range epInfo.IPAddresses {
if ipAddr.IP.To4() != nil {
hnsEndpoint.IPAddress = ipAddr.IP
pl, _ := ipAddr.Mask.Size()
hnsEndpoint.PrefixLength = uint8(pl)
} else {
hnsEndpoint.IPv6Address = ipAddr.IP
pl, _ := ipAddr.Mask.Size()
hnsEndpoint.IPv6PrefixLength = uint8(pl)
if len(nw.Subnets) > 1 {
hnsEndpoint.GatewayAddressV6 = nw.Subnets[1].Gateway.String()
}
}
}
hnsResponse, err := Hnsv1.CreateEndpoint(hnsEndpoint, "")
if err != nil {
return nil, err
}
defer func() {
if err != nil {
logger.Info("HNSEndpointRequest DELETE id", zap.String("id", hnsResponse.Id))
hnsResponse, err := Hnsv1.DeleteEndpoint(hnsResponse.Id)
logger.Error("HNSEndpointRequest DELETE response", zap.Any("hnsResponse", hnsResponse), zap.Error(err))
}
}()
if epInfo.SkipHotAttachEp {
logger.Info("Skipping attaching the endpoint to container",
zap.String("id", hnsResponse.Id), zap.String("id", epInfo.ContainerID))
} else {
// Attach the endpoint.
logger.Info("Attaching endpoint to container", zap.String("id", hnsResponse.Id), zap.String("ContainerID", epInfo.ContainerID))
err = Hnsv1.HotAttachEndpoint(epInfo.ContainerID, hnsResponse.Id)
if err != nil {
logger.Error("Failed to attach endpoint", zap.Error(err))
return nil, err
}
}
// add ipv6 neighbor entry for gateway IP to default mac in container
if err := nw.addIPv6NeighborEntryForGateway(epInfo, plc); err != nil {
return nil, err
}
// Create the endpoint object.
ep := &endpoint{
Id: infraEpName,
HnsId: hnsResponse.Id,
SandboxKey: epInfo.ContainerID,
IfName: epInfo.IfName,
IPAddresses: epInfo.IPAddresses,
Gateways: []net.IP{net.ParseIP(hnsResponse.GatewayAddress)},
DNS: epInfo.EndpointDNS,
VlanID: vlanid,
EnableSnatOnHost: epInfo.EnableSnatOnHost,
NetNs: epInfo.NetNsPath,
ContainerID: epInfo.ContainerID,
NICType: epInfo.NICType,
}
for _, route := range epInfo.Routes {
ep.Routes = append(ep.Routes, route)
}
ep.MacAddress, _ = net.ParseMAC(hnsResponse.MacAddress)
epInfo.HNSEndpointID = hnsResponse.Id // we use the ep info hns id later in stateless to clean up in ADD if there is an error
return ep, nil
}