func (rb *HostgwBackend) checkSubnetExistInRoutes() { routeList, err := netlink.RouteList(nil, netlink.FAMILY_V4) if err == nil { for _, route := range rb.rl { exist := false for _, r := range routeList { if r.Dst == nil { continue } if routeEqual(r, route) { exist = true break } } if !exist { if err := netlink.RouteAdd(&route); err != nil { if nerr, ok := err.(net.Error); !ok { log.Errorf("Error recovering route to %v: %v, %v", route.Dst, route.Gw, nerr) } continue } else { log.Infof("Route recovered %v : %v", route.Dst, route.Gw) } } } } }
func configureIface(ifname string, ipn ip.IP4Net, mtu int) error { iface, err := netlink.LinkByName(ifname) if err != nil { return fmt.Errorf("failed to lookup interface %v", ifname) } err = netlink.AddrAdd(iface, &netlink.Addr{ipn.ToIPNet(), ""}) if err != nil { return fmt.Errorf("failed to add IP address %v to %v: %v", ipn.String(), ifname, err) } err = netlink.LinkSetMTU(iface, mtu) if err != nil { return fmt.Errorf("failed to set MTU for %v: %v", ifname, err) } err = netlink.LinkSetUp(iface) if err != nil { return fmt.Errorf("failed to set interface %v to UP state: %v", ifname, err) } // explicitly add a route since there might be a route for a subnet already // installed by Docker and then it won't get auto added err = netlink.RouteAdd(&netlink.Route{ LinkIndex: iface.Attrs().Index, Scope: netlink.SCOPE_UNIVERSE, Dst: ipn.Network().ToIPNet(), }) if err != nil && err != syscall.EEXIST { return fmt.Errorf("Failed to add route (%v -> %v): %v", ipn.Network().String(), ifname, err) } return nil }
func (rb *HostgwBackend) handleSubnetEvents(batch []subnet.Event) { for _, evt := range batch { switch evt.Type { case subnet.SubnetAdded: log.Infof("Subnet added: %v via %v", evt.Lease.Subnet, evt.Lease.Attrs.PublicIP) if evt.Lease.Attrs.BackendType != "host-gw" { log.Warningf("Ignoring non-host-gw subnet: type=%v", evt.Lease.Attrs.BackendType) continue } route := netlink.Route{ Dst: evt.Lease.Subnet.ToIPNet(), Gw: evt.Lease.Attrs.PublicIP.ToIP(), LinkIndex: rb.extIface.Index, } if rb.extIaddr.Equal(route.Gw) { continue } if err := netlink.RouteAdd(&route); err != nil { log.Errorf("Error adding route to %v via %v: %v", evt.Lease.Subnet, evt.Lease.Attrs.PublicIP, err) continue } rb.addToRouteList(route) case subnet.SubnetRemoved: log.Info("Subnet removed: ", evt.Lease.Subnet) if evt.Lease.Attrs.BackendType != "host-gw" { log.Warningf("Ignoring non-host-gw subnet: type=%v", evt.Lease.Attrs.BackendType) continue } route := netlink.Route{ Dst: evt.Lease.Subnet.ToIPNet(), Gw: evt.Lease.Attrs.PublicIP.ToIP(), LinkIndex: rb.extIface.Index, } if err := netlink.RouteDel(&route); err != nil { log.Errorf("Error deleting route to %v: %v", evt.Lease.Subnet, err) continue } rb.removeFromRouteList(route) default: log.Error("Internal error: unknown event type: ", int(evt.Type)) } } }
func (dev *vxlanDevice) Configure(ipn ip.IP4Net) error { setAddr4(dev.link, ipn.ToIPNet()) if err := netlink.LinkSetUp(dev.link); err != nil { return fmt.Errorf("failed to set interface %s to UP state: %s", dev.link.Attrs().Name, err) } // explicitly add a route since there might be a route for a subnet already // installed by Docker and then it won't get auto added route := netlink.Route{ LinkIndex: dev.link.Attrs().Index, Scope: netlink.SCOPE_UNIVERSE, Dst: ipn.Network().ToIPNet(), } if err := netlink.RouteAdd(&route); err != nil && err != syscall.EEXIST { return fmt.Errorf("failed to add route (%s -> %s): %v", ipn.Network().String(), dev.link.Attrs().Name, err) } return nil }