func()

in controllers/daemon/staticgatewayconfiguration_controller.go [657:750]


func (r *StaticGatewayConfigurationReconciler) reconcileWireguardLink(
	ctx context.Context,
	gwns ns.NetNS,
	gwConfig *egressgatewayv1alpha1.StaticGatewayConfiguration,
	privateKey *wgtypes.Key,
) error {
	log := log.FromContext(ctx)
	linkName := getWireguardInterfaceName(gwConfig)
	var wgLink netlink.Link
	var err error
	if err = gwns.Do(func(nn ns.NetNS) error {
		wgLink, err = r.Netlink.LinkByName(linkName)
		if err != nil {
			if _, ok := err.(netlink.LinkNotFoundError); !ok {
				return fmt.Errorf("failed to get wireguard link in gateway namespace: %w", err)
			}
			wgLink = nil
		}
		return nil
	}); err != nil {
		return err
	}

	if wgLink == nil {
		log.Info("Creating wireguard link")
		if err := r.createWireguardLink(gwns, linkName, string(gwConfig.GetUID())); err != nil {
			return fmt.Errorf("failed to create wireguard link: %w", err)
		}
	}

	return gwns.Do(func(nn ns.NetNS) error {
		wgLink, err := r.Netlink.LinkByName(linkName)
		if err != nil {
			return fmt.Errorf("failed to get wireguard link in gateway namespace after creation: %w", err)
		}
		gwIP, _ := netlink.ParseIPNet(consts.GatewayIP)
		gwLinkAddr := netlink.Addr{
			IPNet: gwIP,
		}

		wgLinkAddrs, err := r.Netlink.AddrList(wgLink, nl.FAMILY_ALL)
		if err != nil {
			return fmt.Errorf("failed to retrieve address list from wireguard link: %w", err)
		}

		foundLink := false
		for _, addr := range wgLinkAddrs {
			if addr.Equal(gwLinkAddr) {
				log.Info("Found wireguard link address")
				foundLink = true
				break
			}
		}

		if !foundLink {
			log.Info("Adding wireguard link address")
			err = r.Netlink.AddrAdd(wgLink, &gwLinkAddr)
			if err != nil {
				return fmt.Errorf("failed to add wireguard link address: %w", err)
			}
		}

		err = r.Netlink.LinkSetUp(wgLink)
		if err != nil {
			return fmt.Errorf("failed to set wireguard link up: %w", err)
		}

		wgClient, err := r.WgCtrl.New()
		if err != nil {
			return fmt.Errorf("failed to create wgctrl client: %w", err)
		}
		defer func() { _ = wgClient.Close() }()

		wgConfig := wgtypes.Config{
			ListenPort: to.Ptr(int(gwConfig.Status.Port)),
			PrivateKey: privateKey,
		}

		device, err := wgClient.Device(linkName)
		if err != nil {
			return fmt.Errorf("failed to get wireguard link configuration: %w", err)
		}

		if device.PrivateKey.String() != wgConfig.PrivateKey.String() || device.ListenPort != to.Val(wgConfig.ListenPort) {
			log.Info("Updating wireguard link config", "orig port", device.ListenPort, "cur port", to.Val(wgConfig.ListenPort),
				"private key difference", device.PrivateKey.String() != wgConfig.PrivateKey.String())
			err = wgClient.ConfigureDevice(linkName, wgConfig)
			if err != nil {
				return fmt.Errorf("failed to add peer to wireguard link: %w", err)
			}
		}
		return nil
	})
}