func()

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
}