func (dev *vxlanDevice) DelRoute(subnet ip.IP4Net) error { route := &netlink.Route{ Scope: netlink.SCOPE_UNIVERSE, Dst: subnet.ToIPNet(), Gw: subnet.IP.ToIP(), } log.Infof("calling RouteDel: %s", subnet) return netlink.RouteDel(route) }
func (dev *vxlanDevice) DelL3(n neigh) error { log.Infof("calling NeighDel: %v, %v", n.IP, n.MAC) return netlink.NeighDel(&netlink.Neigh{ LinkIndex: dev.link.Index, State: netlink.NUD_PERMANENT, Type: syscall.RTN_UNICAST, IP: n.IP.ToIP(), HardwareAddr: n.MAC, }) }
func (dev *vxlanDevice) DelL2(n neigh) error { log.Infof("calling NeighDel: %v, %v", n.IP, n.MAC) return netlink.NeighDel(&netlink.Neigh{ LinkIndex: dev.link.Index, Family: syscall.AF_BRIDGE, Flags: netlink.NTF_SELF, IP: n.IP.ToIP(), HardwareAddr: n.MAC, }) }
func run(be backend.Backend, sm *subnet.SubnetManager, exit chan int) { var err error defer func() { if err == nil || err == task.ErrCanceled { exit <- 0 } else { log.Error(err) exit <- 1 } }() iface, ipaddr, err := lookupIface() if err != nil { return } if iface.MTU == 0 { err = fmt.Errorf("Failed to determine MTU for %s interface", ipaddr) return } log.Infof("Using %s as external interface", ipaddr) sn, err := be.Init(iface, ipaddr, opts.httpPort, opts.ipMasq) if err != nil { return } writeSubnetFile(sn) notifyWebhook(sn) if err = httpServer(sm, ipaddr.String(), opts.httpPort); err != nil { err = fmt.Errorf("error starting HTTP server: %s", err) return } if opts.discoverdURL != "" { disc.NewClientWithURL(opts.discoverdURL).AddServiceAndRegister("flannel", net.JoinHostPort(ipaddr.String(), opts.httpPort)) } log.Infof("%s mode initialized", be.Name()) be.Run() }
func main() { // glog will log to tmp files by default. override so all entries // can flow into journald (if running under systemd) flag.Set("logtostderr", "true") // now parse command line args flag.Parse() if opts.help { fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]...\n", os.Args[0]) flag.PrintDefaults() os.Exit(0) } if opts.version { fmt.Fprintln(os.Stderr, version.String()) os.Exit(0) } flagsFromEnv("FLANNELD", flag.CommandLine) be, sm, err := newBackend() if err != nil { log.Info(err) os.Exit(1) } // Register for SIGINT and SIGTERM and wait for one of them to arrive log.Info("Installing signal handlers") sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) exit := make(chan int) go run(be, sm, exit) for { select { case <-sigs: // unregister to get default OS nuke behaviour in case we don't exit cleanly signal.Stop(sigs) log.Info("Exiting...") be.Stop() case code := <-exit: log.Infof("%s mode exited", be.Name()) os.Exit(code) } } }
func (rb *HostgwBackend) handleSubnetEvents(batch subnet.EventBatch) { for _, evt := range batch { switch evt.Type { case subnet.SubnetAdded: log.Infof("Subnet added: %v via %v", evt.Lease.Network, 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.Network.ToIPNet(), Gw: evt.Lease.Attrs.PublicIP.ToIP(), LinkIndex: rb.extIface.Index, } if err := netlink.RouteAdd(&route); err != nil { log.Errorf("Error adding route to %v via %v: %v", evt.Lease.Network, evt.Lease.Attrs.PublicIP, err) continue } case subnet.SubnetRemoved: log.Info("Subnet removed: ", evt.Lease.Network) 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.Network.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.Network, err) continue } default: log.Error("Internal error: unknown event type: ", int(evt.Type)) } } }
func (sm *SubnetManager) allocateSubnet() (ip.IP4Net, error) { log.Infof("Picking subnet in range %s ... %s", sm.config.SubnetMin, sm.config.SubnetMax) var bag []ip.IP4 sn := ip.IP4Net{IP: sm.config.SubnetMin, PrefixLen: sm.config.SubnetLen} OuterLoop: for ; sn.IP <= sm.config.SubnetMax && len(bag) < 100; sn = sn.Next() { for _, l := range sm.leases { if sn.Overlaps(l.Network) { continue OuterLoop } } bag = append(bag, sn.IP) } if len(bag) == 0 { return ip.IP4Net{}, errors.New("out of subnets") } else { i := randInt(0, len(bag)) return ip.IP4Net{IP: bag[i], PrefixLen: sm.config.SubnetLen}, nil } }