Beispiel #1
0
// ipvsService returns an IPVS Service for the given service.
func (svc *service) ipvsService() *ipvs.Service {
	var flags ipvs.ServiceFlags
	if svc.ventry.Persistence > 0 {
		flags |= ipvs.SFPersistent
	}
	if svc.ventry.OnePacket {
		flags |= ipvs.SFOnePacket
	}
	var ip net.IP
	switch {
	case svc.fwm > 0 && svc.af == seesaw.IPv4:
		ip = net.IPv4zero
	case svc.fwm > 0 && svc.af == seesaw.IPv6:
		ip = net.IPv6zero
	default:
		ip = svc.ip.IP()
	}
	return &ipvs.Service{
		Address:      ip,
		Protocol:     ipvs.IPProto(svc.proto),
		Port:         svc.port,
		Scheduler:    svc.ventry.Scheduler.String(),
		FirewallMark: svc.fwm,
		Flags:        flags,
		Timeout:      uint32(svc.ventry.Persistence),
	}
}
Beispiel #2
0
// markBackend returns a mark for the specified backend and sets up the IPVS
// service entry if it does not exist.
func (h *healthcheckManager) markBackend(backend seesaw.IP) uint32 {
	mark, ok := h.marks[backend]
	if ok {
		return mark
	}

	mark, err := h.markAlloc.get()
	if err != nil {
		log.Fatalf("Failed to get mark: %v", err)
	}
	h.marks[backend] = mark

	ip := net.IPv6zero
	if backend.AF() == seesaw.IPv4 {
		ip = net.IPv4zero
	}

	ipvsSvc := &ipvs.Service{
		Address:      ip,
		Protocol:     ipvs.IPProto(0),
		Port:         0,
		Scheduler:    "rr",
		FirewallMark: mark,
		Destinations: []*ipvs.Destination{
			{
				Address: backend.IP(),
				Port:    0,
				Weight:  1,
				Flags:   ipvs.DFForwardRoute,
			},
		},
	}

	if err := h.ncc.Dial(); err != nil {
		log.Fatalf("Failed to connect to NCC: %v", err)
	}
	defer h.ncc.Close()

	log.Infof("Adding DSR IPVS service for %s (mark %d)", backend, mark)
	if err := h.ncc.IPVSAddService(ipvsSvc); err != nil {
		log.Fatalf("Failed to add IPVS service for DSR: %v", err)
	}

	return mark
}
Beispiel #3
0
// unmarkBackend removes the mark for a given backend and removes the IPVS
// service entry if it exists.
func (h *healthcheckManager) unmarkBackend(backend seesaw.IP) {
	mark, ok := h.marks[backend]
	if !ok {
		return
	}

	ip := net.IPv6zero
	if backend.AF() == seesaw.IPv4 {
		ip = net.IPv4zero
	}

	ipvsSvc := &ipvs.Service{
		Address:      ip,
		Protocol:     ipvs.IPProto(0),
		Port:         0,
		Scheduler:    "rr",
		FirewallMark: mark,
		Destinations: []*ipvs.Destination{
			{
				Address: backend.IP(),
				Port:    0,
				Weight:  1,
				Flags:   ipvs.DFForwardRoute,
			},
		},
	}

	if err := h.ncc.Dial(); err != nil {
		log.Fatalf("Failed to connect to NCC: %v", err)
	}
	defer h.ncc.Close()

	log.Infof("Removing DSR IPVS service for %s (mark %d)", backend, mark)
	if err := h.ncc.IPVSDeleteService(ipvsSvc); err != nil {
		log.Fatalf("Failed to remove DSR IPVS service: %v", err)
	}

	delete(h.marks, backend)
	h.markAlloc.put(mark)
}