protocol in BIRD, when the node is a primary subnet router as determined by control. Signed-off-by: Maisem Ali <maisem@tailscale.com>main
parent
7fcf86a14a
commit
fd4838dc57
@ -0,0 +1,83 @@ |
||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package chirp implements a client to communicate with the BIRD Internet
|
||||
// Routing Daemon.
|
||||
package chirp |
||||
|
||||
import ( |
||||
"bufio" |
||||
"fmt" |
||||
"net" |
||||
"strings" |
||||
) |
||||
|
||||
// New creates a BIRDClient.
|
||||
func New(socket string) (*BIRDClient, error) { |
||||
conn, err := net.Dial("unix", socket) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to connect to BIRD: %w", err) |
||||
} |
||||
b := &BIRDClient{socket: socket, conn: conn, bs: bufio.NewScanner(conn)} |
||||
// Read and discard the first line as that is the welcome message.
|
||||
if _, err := b.readLine(); err != nil { |
||||
return nil, err |
||||
} |
||||
return b, nil |
||||
} |
||||
|
||||
// BIRDClient handles communication with the BIRD Internet Routing Daemon.
|
||||
type BIRDClient struct { |
||||
socket string |
||||
conn net.Conn |
||||
bs *bufio.Scanner |
||||
} |
||||
|
||||
// Close closes the underlying connection to BIRD.
|
||||
func (b *BIRDClient) Close() error { return b.conn.Close() } |
||||
|
||||
// DisableProtocol disables the provided protocol.
|
||||
func (b *BIRDClient) DisableProtocol(protocol string) error { |
||||
out, err := b.exec("disable %s\n", protocol) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
if strings.Contains(out, fmt.Sprintf("%s: already disabled", protocol)) { |
||||
return nil |
||||
} else if strings.Contains(out, fmt.Sprintf("%s: disabled", protocol)) { |
||||
return nil |
||||
} |
||||
return fmt.Errorf("failed to disable %s: %v", protocol, out) |
||||
} |
||||
|
||||
// EnableProtocol enables the provided protocol.
|
||||
func (b *BIRDClient) EnableProtocol(protocol string) error { |
||||
out, err := b.exec("enable %s\n", protocol) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
if strings.Contains(out, fmt.Sprintf("%s: already enabled", protocol)) { |
||||
return nil |
||||
} else if strings.Contains(out, fmt.Sprintf("%s: enabled", protocol)) { |
||||
return nil |
||||
} |
||||
return fmt.Errorf("failed to enable %s: %v", protocol, out) |
||||
} |
||||
|
||||
func (b *BIRDClient) exec(cmd string, args ...interface{}) (string, error) { |
||||
if _, err := fmt.Fprintf(b.conn, cmd, args...); err != nil { |
||||
return "", err |
||||
} |
||||
return b.readLine() |
||||
} |
||||
|
||||
func (b *BIRDClient) readLine() (string, error) { |
||||
if !b.bs.Scan() { |
||||
return "", fmt.Errorf("reading response from bird failed") |
||||
} |
||||
if err := b.bs.Err(); err != nil { |
||||
return "", err |
||||
} |
||||
return b.bs.Text(), nil |
||||
} |
||||
@ -0,0 +1,19 @@ |
||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux || darwin || freebsd || openbsd
|
||||
// +build linux darwin freebsd openbsd
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"tailscale.com/chirp" |
||||
"tailscale.com/wgengine" |
||||
) |
||||
|
||||
func init() { |
||||
createBIRDClient = func(ctlSocket string) (wgengine.BIRDClient, error) { |
||||
return chirp.New(ctlSocket) |
||||
} |
||||
} |
||||
@ -0,0 +1,16 @@ |
||||
log syslog all; |
||||
|
||||
protocol device { |
||||
scan time 10; |
||||
} |
||||
|
||||
protocol bgp { |
||||
local as 64001; |
||||
neighbor 10.40.2.101 as 64002; |
||||
ipv4 { |
||||
import none; |
||||
export all; |
||||
}; |
||||
} |
||||
|
||||
include "tailscale_bird.conf"; |
||||
@ -0,0 +1,4 @@ |
||||
protocol static tailscale { |
||||
ipv4; |
||||
route 100.64.0.0/10 via "tailscale0"; |
||||
} |
||||
Loading…
Reference in new issue