diff --git a/net/tcp/listen.go b/net/tcp/listen.go index 2e281a84..cf0f2dd6 100644 --- a/net/tcp/listen.go +++ b/net/tcp/listen.go @@ -9,7 +9,7 @@ import ( ) type ListenerFactoryI interface { - NewListener(v *vrf.VRF, laddr *net.TCPAddr, ttl uint8) (ListenerI, error) + NewListener(v *vrf.VRF, laddr *net.TCPAddr, ttl uint8, reuseport bool) (ListenerI, error) } type ListenerFactory struct{} @@ -30,7 +30,7 @@ type Listener struct { } // NewListener starts a TCPListener -func (lf *ListenerFactory) NewListener(v *vrf.VRF, laddr *net.TCPAddr, ttl uint8) (ListenerI, error) { +func (lf *ListenerFactory) NewListener(v *vrf.VRF, laddr *net.TCPAddr, ttl uint8, reuseport bool) (ListenerI, error) { l := &Listener{ laddr: laddr, } @@ -57,13 +57,14 @@ func (lf *ListenerFactory) NewListener(v *vrf.VRF, laddr *net.TCPAddr, ttl uint8 err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) if err != nil { unix.Close(fd) - return nil, fmt.Errorf("unable to get SO_REUSEADDR %w", err) + return nil, fmt.Errorf("unable to set SO_REUSEADDR %w", err) } - err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) - if err != nil { - unix.Close(fd) - return nil, fmt.Errorf("unable to get SO_REUSEPORT %w", err) + if reuseport { + if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil { + unix.Close(fd) + return nil, fmt.Errorf("unable to set SO_REUSEPORT %w", err) + } } if ttl != 0 { diff --git a/net/tcp/listener_manager.go b/net/tcp/listener_manager.go index 102d0423..c5a05842 100644 --- a/net/tcp/listener_manager.go +++ b/net/tcp/listener_manager.go @@ -27,14 +27,16 @@ type ListenerManager struct { listenersByVRFmu sync.RWMutex acceptCh chan ConnWithVRF listenerFactory ListenerFactoryI + reusePort bool } -func NewListenerManager(listenAddrsByVRF map[string][]string) *ListenerManager { +func NewListenerManager(listenAddrsByVRF map[string][]string, reusePort bool) *ListenerManager { return &ListenerManager{ listenAddrsByVRF: listenAddrsByVRF, listenersByVRF: make(map[string][]ListenerI), listenerFactory: NewListenerFactory(), acceptCh: make(chan ConnWithVRF), + reusePort: reusePort, } } @@ -93,7 +95,7 @@ func (lm *ListenerManager) _addListener(vrf *vrf.VRF, addr string, ch chan ConnW } log.Infof("Listener manager: Starting TCP listener on %s in VRF %s", addr, vrf.Name()) - l, err := lm.listenerFactory.NewListener(vrf, tcpaddr, 255) + l, err := lm.listenerFactory.NewListener(vrf, tcpaddr, 255, lm.reusePort) if err != nil { return err } diff --git a/protocols/bgp/server/server.go b/protocols/bgp/server/server.go index 1bba09ff..fc065e7c 100644 --- a/protocols/bgp/server/server.go +++ b/protocols/bgp/server/server.go @@ -29,6 +29,7 @@ type BGPServerConfig struct { // Optional attributes DefaultLocalPreference *uint32 + ReusePort bool } type bgpServer struct { @@ -68,7 +69,7 @@ func newBGPServer(config BGPServerConfig) *bgpServer { server := &bgpServer{ config: config, peers: newPeerManager(), - listenerManager: tcp.NewListenerManager(config.ListenAddrsByVRF), + listenerManager: tcp.NewListenerManager(config.ListenAddrsByVRF, config.ReusePort), } server.metrics = &metricsService{server}