예제 #1
0
func (o *Overlay) addPolicies(policies map[string]netlink.XfrmPolicy) error {
	var lastErr error
	for _, policy := range policies {
		if err := netlink.XfrmPolicyAdd(&policy); err != nil {
			logrus.Errorf("Failed to add policy: %+v, %v", policy, err)
			lastErr = err
		} else {
			logrus.Infof("Added policy: %+v", policy)
		}
	}
	return lastErr
}
예제 #2
0
func buildTunnelLocal(dst net.IP, tunnel *client.Tunnel) (net.IP, *client.Tunnel, error) {
	var socket int
	if tunnel.SrcPort != 0 {
		var err error
		socket, err = createEncapListener(tunnel.Src, tunnel.SrcPort)
		if err != nil {
			glog.Errorf("Failed to create udp listener: %v", err)
			return nil, nil, err
		}
	}
	addTunnel(dst.String(), tunnel, socket)

	src := opts.src

	srcNet := netlink.NewIPNet(tunnel.Src)
	dstNet := netlink.NewIPNet(tunnel.Dst)

	glog.Infof("Building tunnel: %v, %v", tunnel.Src, tunnel.Dst)
	// add IP address to loopback device
	lo, err := netlink.LinkByName("lo")
	if err != nil {
		glog.Errorf("Failed to get loopback device: %v", err)
		return nil, nil, err
	}
	err = netlink.AddrAdd(lo, &netlink.Addr{IPNet: srcNet})
	if err != nil {
		glog.Errorf("Failed to add %v to loopback: %v", tunnel.Src, err)
		return nil, nil, err
	}

	index, err := getLinkIndex(src)
	if err != nil {
		glog.Errorf("Failed to get link for address: %v", err)
		return nil, nil, err
	}
	// add source route to tunnel ips device
	route := &netlink.Route{
		Scope:     netlink.SCOPE_LINK,
		Src:       tunnel.Src,
		Dst:       dstNet,
		LinkIndex: index,
	}
	err = netlink.RouteAdd(route)
	if err != nil {
		glog.Errorf("Failed to add route %v: %v", route, err)
		return nil, nil, err
	}

	for _, policy := range getPolicies(tunnel.Reqid, src, dst, srcNet, dstNet) {
		glog.Infof("building Policy: %v", policy)
		// create xfrm policy rules
		err = netlink.XfrmPolicyAdd(&policy)
		if err != nil {
			if err == syscall.EEXIST {
				glog.Infof("Skipped adding policy %v because it already exists", policy)
			} else {
				glog.Errorf("Failed to add policy %v: %v", policy, err)
				return nil, nil, err
			}
		}
	}
	for _, state := range getStates(tunnel.Reqid, src, dst, tunnel.SrcPort, tunnel.DstPort, tunnel.AuthKey, tunnel.EncKey) {
		glog.Infof("building State: %v", state)
		// crate xfrm state rules
		err = netlink.XfrmStateAdd(&state)
		if err != nil {
			if err == syscall.EEXIST {
				glog.Infof("Skipped adding state %v because it already exists", state)
			} else {
				glog.Errorf("Failed to add state %v: %v", state, err)
				return nil, nil, err
			}
		}
	}
	glog.Infof("Finished building tunnel: %v, %v", tunnel.Src, tunnel.Dst)
	return opts.external, tunnel, nil
}