ipv6 support wip

This commit is contained in:
mgaitonde
2023-08-18 16:23:47 -07:00
parent e3ed374b53
commit 645b10548a
4 changed files with 51 additions and 13 deletions

View File

@@ -21,6 +21,12 @@ bgp:
- asn:nnnn - asn:nnnn
- asn:nnnn - asn:nnnn
origin: igp origin: igp
# family will determine whether we want to peer over an ipv4 or ipv6 session
# one gocast instance can only peer over one session. Multiple sessions are not
# supported. The default is 4
family: 4
# router ID is required when family 6 is specified
router_id: 1.1.1.1
# optional list of apps to register on startup # optional list of apps to register on startup
apps: apps:

View File

@@ -15,7 +15,7 @@ type AgentConfig struct {
CleanupTimer time.Duration `yaml:"cleanup_timer"` CleanupTimer time.Duration `yaml:"cleanup_timer"`
ConsulAddr string `yaml:"consul_addr"` ConsulAddr string `yaml:"consul_addr"`
ConsulQueryInterval time.Duration `yaml:"consul_query_interval"` ConsulQueryInterval time.Duration `yaml:"consul_query_interval"`
ConsulToken string `yaml:"consul_token"` ConsulToken string `yaml:"consul_token"`
} }
type BgpConfig struct { type BgpConfig struct {
@@ -25,6 +25,8 @@ type BgpConfig struct {
PeerIP string `yaml:"peer_ip"` PeerIP string `yaml:"peer_ip"`
Communities []string Communities []string
Origin string Origin string
Family int
RouterID string `yaml:"router_id"`
} }
type VipConfig struct { type VipConfig struct {

View File

@@ -32,10 +32,13 @@ func NewController(config c.BgpConfig) (*Controller, error) {
c := &Controller{} c := &Controller{}
var gw net.IP var gw net.IP
var err error var err error
if config.Family == 0 {
config.Family = 4
}
if config.PeerIP == "" { if config.PeerIP == "" {
gw, err := gateway() gw, err := gateway(config.Family)
if err != nil { if err != nil {
return nil, fmt.Errorf("Unable to get gw ip: %v", err) return nil, fmt.Errorf("unable to get gw ip: %v", err)
} }
c.peerIP = gw c.peerIP = gw
} else { } else {
@@ -44,7 +47,7 @@ func NewController(config c.BgpConfig) (*Controller, error) {
if config.LocalIP == "" { if config.LocalIP == "" {
gw, err = via(c.peerIP) gw, err = via(c.peerIP)
if err != nil { if err != nil {
return nil, fmt.Errorf("Unable to get gw ip: %v", err) return nil, fmt.Errorf("unable to get gw ip: %v", err)
} }
c.localIP, err = localAddress(gw) c.localIP, err = localAddress(gw)
if err != nil { if err != nil {
@@ -62,16 +65,23 @@ func NewController(config c.BgpConfig) (*Controller, error) {
case "unknown": case "unknown":
c.origin = 2 c.origin = 2
} }
var rid string
if config.Family == 4 {
rid = c.localIP.String()
}
if config.RouterID != "" {
rid = config.RouterID
}
s := gobgp.NewBgpServer() s := gobgp.NewBgpServer()
go s.Serve() go s.Serve()
if err := s.StartBgp(context.Background(), &api.StartBgpRequest{ if err := s.StartBgp(context.Background(), &api.StartBgpRequest{
Global: &api.Global{ Global: &api.Global{
As: uint32(config.LocalAS), As: uint32(config.LocalAS),
RouterId: c.localIP.String(), RouterId: rid,
ListenPort: -1, // gobgp won't listen on tcp:179 ListenPort: -1, // gobgp won't listen on tcp:179
}, },
}); err != nil { }); err != nil {
return nil, fmt.Errorf("Unable to start bgp: %v", err) return nil, fmt.Errorf("unable to start bgp: %v", err)
} }
c.s = s c.s = s
c.peerAS = config.PeerAS c.peerAS = config.PeerAS

View File

@@ -18,8 +18,12 @@ func getCmdList(mainCmd string) []string {
return cmdList return cmdList
} }
func gateway() (net.IP, error) { func gateway(family int) (net.IP, error) {
cmd := `ip route | grep "^default" | cut -d" " -f3` prefix := "ip"
if family == 6 {
prefix = "ip -6"
}
cmd := fmt.Sprintf(`%s route | grep "^default" | cut -d" " -f3`, prefix)
cmdList := getCmdList(cmd) cmdList := getCmdList(cmd)
out, err := exec.Command(execCmd, cmdList...).Output() out, err := exec.Command(execCmd, cmdList...).Output()
if err != nil { if err != nil {
@@ -29,7 +33,11 @@ func gateway() (net.IP, error) {
} }
func via(dest net.IP) (net.IP, error) { func via(dest net.IP) (net.IP, error) {
cmd := fmt.Sprintf(`ip route get %s | grep via | cut -d" " -f3`, dest.String()) prefix := "ip"
if dest.To4() == nil {
prefix = "ip -6"
}
cmd := fmt.Sprintf(`%s route get %s | grep via | cut -d" " -f3`, prefix, dest.String())
cmdList := getCmdList(cmd) cmdList := getCmdList(cmd)
out, err := exec.Command(execCmd, cmdList...).Output() out, err := exec.Command(execCmd, cmdList...).Output()
if err != nil { if err != nil {
@@ -66,7 +74,11 @@ func addLoopback(name string, addr *net.IPNet) error {
if len(label) > 15 { if len(label) > 15 {
label = label[:15] label = label[:15]
} }
cmd := fmt.Sprintf("ip address add %s/%d dev lo label %s", addr.IP.String(), prefixLen, label) prefix := "ip"
if addr.IP.To4() == nil {
prefix = "ip -6"
}
cmd := fmt.Sprintf("%s address add %s/%d dev lo label %s", prefix, addr.IP.String(), prefixLen, label)
cmdList := getCmdList(cmd) cmdList := getCmdList(cmd)
_, err := exec.Command(execCmd, cmdList...).Output() _, err := exec.Command(execCmd, cmdList...).Output()
if err != nil { if err != nil {
@@ -76,8 +88,12 @@ func addLoopback(name string, addr *net.IPNet) error {
} }
func deleteLoopback(addr *net.IPNet) error { func deleteLoopback(addr *net.IPNet) error {
prefix := "ip"
if addr.IP.To4() == nil {
prefix = "ip -6"
}
prefixLen, _ := addr.Mask.Size() prefixLen, _ := addr.Mask.Size()
cmd := fmt.Sprintf("ip address delete %s/%d dev lo", addr.IP.String(), prefixLen) cmd := fmt.Sprintf("%s address delete %s/%d dev lo", prefix, addr.IP.String(), prefixLen)
cmdList := getCmdList(cmd) cmdList := getCmdList(cmd)
_, err := exec.Command(execCmd, cmdList...).Output() _, err := exec.Command(execCmd, cmdList...).Output()
if err != nil { if err != nil {
@@ -87,9 +103,13 @@ func deleteLoopback(addr *net.IPNet) error {
} }
func natRule(op string, vip, localAddr net.IP, protocol, lport, dport string) error { func natRule(op string, vip, localAddr net.IP, protocol, lport, dport string) error {
prefix := "iptables"
if vip.To4() == nil {
prefix = "ip6tables"
}
cmd := fmt.Sprintf( cmd := fmt.Sprintf(
"iptables -t nat -%s PREROUTING -p %s -d %s --dport %s -j DNAT --to-destination %s:%s", "%s -t nat -%s PREROUTING -p %s -d %s --dport %s -j DNAT --to-destination %s:%s",
op, protocol, vip.String(), lport, localAddr.String(), dport, prefix, op, protocol, vip.String(), lport, localAddr.String(), dport,
) )
cmdList := getCmdList(cmd) cmdList := getCmdList(cmd)
_, err := exec.Command(execCmd, cmdList...).Output() _, err := exec.Command(execCmd, cmdList...).Output()