Skip to content

Commit

Permalink
BGP connection on a speecified interface (including which is associat…
Browse files Browse the repository at this point in the history
…ed VRF) using syscall SO_BINDTODEVICE
  • Loading branch information
irino authored and fujita committed Jul 2, 2019
1 parent 9f93606 commit 2f5a4d5
Show file tree
Hide file tree
Showing 11 changed files with 547 additions and 501 deletions.
991 changes: 500 additions & 491 deletions api/gobgp.pb.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions api/gobgp.proto
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ message Transport {
string remote_address = 5;
uint32 remote_port = 6;
uint32 tcp_mss = 7;
string bind_interface = 8;
}

message RouteServer {
Expand Down
11 changes: 11 additions & 0 deletions internal/pkg/config/bgp_configs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2548,6 +2548,10 @@ type TransportState struct {
// Remote port being used by the peer for the TCP session
// supporting the BGP session.
RemotePort uint16 `mapstructure:"remote-port" json:"remote-port,omitempty"`
// original -> bgp:bind-interface
// bgp:bind-interface's original type is union.
// Interface name for binding.
BindInterface string `mapstructure:"bind-interface" json:"bind-interface,omitempty"`
}

// struct for container bgp:config.
Expand Down Expand Up @@ -2580,6 +2584,10 @@ type TransportConfig struct {
// original -> gobgp:ttl
// TTL value for BGP packets.
Ttl uint8 `mapstructure:"ttl" json:"ttl,omitempty"`
// original -> bgp:bind-interface
// bgp:bind-interface's original type is union.
// Interface name for binding.
BindInterface string `mapstructure:"bind-interface" json:"bind-interface,omitempty"`
}

func (lhs *TransportConfig) Equal(rhs *TransportConfig) bool {
Expand All @@ -2604,6 +2612,9 @@ func (lhs *TransportConfig) Equal(rhs *TransportConfig) bool {
if lhs.Ttl != rhs.Ttl {
return false
}
if lhs.BindInterface != rhs.BindInterface {
return false
}
return true
}

Expand Down
7 changes: 4 additions & 3 deletions internal/pkg/config/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,9 +534,10 @@ func NewPeerFromConfigStruct(pconf *Neighbor) *api.Peer {
LocalRestarting: pconf.GracefulRestart.State.LocalRestarting,
},
Transport: &api.Transport{
RemotePort: uint32(pconf.Transport.Config.RemotePort),
LocalAddress: localAddress,
PassiveMode: pconf.Transport.Config.PassiveMode,
RemotePort: uint32(pconf.Transport.Config.RemotePort),
LocalAddress: localAddress,
PassiveMode: pconf.Transport.Config.PassiveMode,
BindInterface: pconf.Transport.Config.BindInterface,
},
AfiSafis: afiSafis,
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/server/fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ func (h *fsmHandler) connectLoop(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
fsm := h.fsm

retry, addr, port, password, ttl, ttlMin, localAddress := func() (int, string, int, string, uint8, uint8, string) {
retry, addr, port, password, ttl, ttlMin, localAddress, bindInterface := func() (int, string, int, string, uint8, uint8, string, string) {
fsm.lock.RLock()
defer fsm.lock.RUnlock()

Expand All @@ -518,7 +518,7 @@ func (h *fsmHandler) connectLoop(ctx context.Context, wg *sync.WaitGroup) {
ttl = fsm.pConf.EbgpMultihop.Config.MultihopTtl
}
}
return tick, addr, port, password, ttl, ttlMin, fsm.pConf.Transport.Config.LocalAddress
return tick, addr, port, password, ttl, ttlMin, fsm.pConf.Transport.Config.LocalAddress, fsm.pConf.Transport.Config.BindInterface
}()

tick := minConnectRetryInterval
Expand Down Expand Up @@ -553,7 +553,7 @@ func (h *fsmHandler) connectLoop(ctx context.Context, wg *sync.WaitGroup) {
LocalAddr: laddr,
Timeout: time.Duration(tick-1) * time.Second,
Control: func(network, address string, c syscall.RawConn) error {
return dialerControl(network, address, c, ttl, ttlMin, password)
return dialerControl(network, address, c, ttl, ttlMin, password, bindInterface)
},
}

Expand Down
1 change: 1 addition & 0 deletions pkg/server/grpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ func newNeighborFromAPIStruct(a *api.Peer) (*config.Neighbor, error) {
pconf.Transport.Config.LocalAddress = a.Transport.LocalAddress
pconf.Transport.Config.PassiveMode = a.Transport.PassiveMode
pconf.Transport.Config.RemotePort = uint16(a.Transport.RemotePort)
pconf.Transport.Config.BindInterface = a.Transport.BindInterface
}
if a.EbgpMultihop != nil {
pconf.EbgpMultihop.Config.Enabled = a.EbgpMultihop.Enabled
Expand Down
4 changes: 3 additions & 1 deletion pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ func (s *BgpServer) passConnToPeer(conn *net.TCPConn) {
}
peer.fsm.lock.RLock()
localAddr := peer.fsm.pConf.Transport.Config.LocalAddress
bindInterface := peer.fsm.pConf.Transport.Config.BindInterface
peer.fsm.lock.RUnlock()
localAddrValid := func(laddr string) bool {
if laddr == "0.0.0.0" || laddr == "::" {
Expand All @@ -262,12 +263,13 @@ func (s *BgpServer) passConnToPeer(conn *net.TCPConn) {
}

host, _, _ := net.SplitHostPort(l.String())
if host != laddr {
if host != laddr && bindInterface == "" {
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": remoteAddr,
"Configured addr": laddr,
"Addr": host,
"BindInterface": bindInterface,
}).Info("Mismatched local address")
return false
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/sockopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func setTCPMinTTLSockopt(conn *net.TCPConn, ttl int) error {
return setTcpMinTTLSockopt(conn, ttl)
}

func dialerControl(network, address string, c syscall.RawConn, ttl, ttlMin uint8, password string) error {
func dialerControl(network, address string, c syscall.RawConn, ttl, ttlMin uint8, password string, bindInterface string) error {
if password != "" {
log.WithFields(log.Fields{
"Topic": "Peer",
Expand Down
12 changes: 11 additions & 1 deletion pkg/server/sockopt_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func setTCPMinTTLSockopt(conn *net.TCPConn, ttl int) error {
return setsockOptInt(sc, level, name, ttl)
}

func dialerControl(network, address string, c syscall.RawConn, ttl, minTtl uint8, password string) error {
func dialerControl(network, address string, c syscall.RawConn, ttl, minTtl uint8, password string, bindInterface string) error {
family := syscall.AF_INET
raddr, _ := net.ResolveTCPAddr("tcp", address)
if raddr.IP.To4() == nil {
Expand Down Expand Up @@ -161,5 +161,15 @@ func dialerControl(network, address string, c syscall.RawConn, ttl, minTtl uint8
return sockerr
}
}
if bindInterface != "" {
if err := c.Control(func(fd uintptr) {
sockerr = os.NewSyscallError("setsockopt", syscall.SetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, bindInterface))
}); err != nil {
return err
}
if sockerr != nil {
return sockerr
}
}
return nil
}
2 changes: 1 addition & 1 deletion pkg/server/sockopt_openbsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ func setTCPMinTTLSockopt(conn *net.TCPConn, ttl int) error {
return setsockOptInt(sc, level, name, ttl)
}

func dialerControl(network, address string, c syscall.RawConn, ttl, minTtl uint8, password string) error {
func dialerControl(network, address string, c syscall.RawConn, ttl, minTtl uint8, password string, bindInterface string) error {
if password != "" {
log.WithFields(log.Fields{
"Topic": "Peer",
Expand Down
11 changes: 11 additions & 0 deletions tools/pyang_plugins/gobgp.yang
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,11 @@ module gobgp {
description "TTL value for BGP packets";
type uint8;
}

leaf bind-interface {
description "Interface name for binding.";
type string;
}
}

augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:timers/bgp:config" {
Expand Down Expand Up @@ -1239,6 +1244,12 @@ module gobgp {
"Configure MPLS label range size which will be requested to
FRR/Zebra.";
}
leaf software-name {
type string;
description
"Configure zebra software name.
quagga, frr3, frr4, frr5, frr6, frr7 can be used.";
}
}

grouping zebra-set {
Expand Down

0 comments on commit 2f5a4d5

Please sign in to comment.