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 }
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 }