Example #1
0
// iptablesFlush removes all IPv4 and IPv6 iptables rules.
func iptablesFlush() error {
	for _, af := range seesaw.AFs() {
		for _, table := range []string{"filter", "mangle", "raw"} {
			if err := iptablesRun(af, fmt.Sprintf("--flush -t %v", table)); err != nil {
				return err
			}
		}
	}
	// NAT is IPv4-only until linux kernel version 3.7.
	// TODO(angusc): Support IPv6 NAT.
	if err := iptablesRun(seesaw.IPv4, "--flush -t nat"); err != nil {
		return err
	}
	return nil
}
Example #2
0
// expandFWMServices returns a list of services that have been expanded from the
// vserver configuration for a firewall mark based vserver.
func (v *vserver) expandFWMServices() map[serviceKey]*service {
	svcs := make(map[serviceKey]*service)
	for _, af := range seesaw.AFs() {
		var ip net.IP
		switch af {
		case seesaw.IPv4:
			ip = v.config.Host.IPv4Addr
		case seesaw.IPv6:
			ip = v.config.Host.IPv6Addr
		}
		if ip == nil {
			continue
		}

		// Persistence, etc., is stored in the VserverEntry. For FWM services, these
		// values must be the same for all VserverEntries, so just use the first
		// one.
		var ventry *config.VserverEntry
		for _, entry := range v.config.Entries {
			ventry = entry
			break
		}

		if v.fwm[af] == 0 {
			mark, err := v.engine.fwmAlloc.get()
			if err != nil {
				log.Fatalf("%v: failed to get mark: %v", v, err)
			}
			v.fwm[af] = mark
		}
		svc := &service{
			serviceKey: serviceKey{
				af:  af,
				fwm: v.fwm[af],
			},
			ip:      seesaw.NewIP(ip),
			ventry:  ventry,
			vserver: v,
			stats:   &seesaw.ServiceStats{},
		}
		svc.ipvsSvc = svc.ipvsService()
		svcs[svc.serviceKey] = svc
	}
	return svcs
}
Example #3
0
// iptablesInit initialises the iptables rules for a Seesaw Node.
func iptablesInit(clusterVIP seesaw.Host) error {
	if err := iptablesFlush(); err != nil {
		return err
	}
	for _, af := range seesaw.AFs() {
		// Allow connections to port 10257 for all VIPs.
		if err := iptablesRun(af, "-I INPUT -p tcp --dport 10257 -j ACCEPT"); err != nil {
			return err
		}

		// conntrack is only required for NAT. Disable it for everything else.
		if err := iptablesRun(af, "-t raw -A PREROUTING -j NOTRACK"); err != nil {
			return err
		}
		if err := iptablesRun(af, "-t raw -A OUTPUT -j NOTRACK"); err != nil {
			return err
		}
	}

	// Enable conntrack for incoming traffic on the seesaw cluster IPv4 VIP. This
	// is required for NAT return traffic.
	return iptablesRun(seesaw.IPv4,
		fmt.Sprintf("-t raw -I PREROUTING -d %v/32 -j ACCEPT", clusterVIP.IPv4Addr))
}
Example #4
0
// expandServices returns a list of services that have been expanded from the
// vserver configuration.
func (v *vserver) expandServices() map[serviceKey]*service {
	if v.config.UseFWM {
		return v.expandFWMServices()
	}

	svcs := make(map[serviceKey]*service)
	for _, af := range seesaw.AFs() {
		var ip net.IP
		switch af {
		case seesaw.IPv4:
			ip = v.config.Host.IPv4Addr
		case seesaw.IPv6:
			ip = v.config.Host.IPv6Addr
		}
		if ip == nil {
			continue
		}
		for _, entry := range v.config.Entries {
			svc := &service{
				serviceKey: serviceKey{
					af:    af,
					proto: entry.Proto,
					port:  entry.Port,
				},
				ip:      seesaw.NewIP(ip),
				ventry:  entry,
				vserver: v,
				dests:   make(map[destinationKey]*destination, 0),
				stats:   &seesaw.ServiceStats{},
			}
			svc.ipvsSvc = svc.ipvsService()
			svcs[svc.serviceKey] = svc
		}
	}
	return svcs
}