Skip to content

Commit

Permalink
bgp: support md5 authentication for pro-active sessions
Browse files Browse the repository at this point in the history
For now, only Linux is supported.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
  • Loading branch information
fujita committed Jun 30, 2014
1 parent 24220ea commit b984c15
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
33 changes: 21 additions & 12 deletions ryu/services/protocols/bgp/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import netaddr

from ryu.lib import hub
from ryu.lib import sockopt
from ryu.lib.hub import Timeout
from ryu.lib.packet.bgp import RF_IPv4_UC
from ryu.lib.packet.bgp import RF_IPv6_UC
Expand Down Expand Up @@ -353,7 +354,7 @@ def _listen_tcp(self, loc_addr, conn_handle):
self._spawn(client_name, conn_handle, sock)

def _connect_tcp(self, peer_addr, conn_handler, time_out=None,
bind_address=None):
bind_address=None, password=None):
"""Creates a TCP connection to given peer address.
Tries to create a socket for `timeout` number of seconds. If
Expand All @@ -367,17 +368,25 @@ def _connect_tcp(self, peer_addr, conn_handler, time_out=None,
else:
family = socket.AF_INET6
with Timeout(time_out, socket.error):
sock = hub.connect(peer_addr, family=family, bind=bind_address)
if sock:
# Connection name for pro-active connection is made up
# of local end address + remote end address
local = self.get_localname(sock)[0]
remote = self.get_remotename(sock)[0]
conn_name = ('L: ' + local + ', R: ' + remote)
self._asso_socket_map[conn_name] = sock
# If connection is established, we call connection handler
# in a new thread.
self._spawn(conn_name, conn_handler, sock)
sock = socket.socket(family)
if bind_address:
sock.bind(bind_address)
if password:
sockopt.set_tcp_md5sig(sock, peer_addr[0], password)
sock.connect(peer_addr)
# socket.error exception is rasied in cese of timeout and
# the following code is executed only when the connection
# is established.

# Connection name for pro-active connection is made up of
# local end address + remote end address
local = self.get_localname(sock)[0]
remote = self.get_remotename(sock)[0]
conn_name = ('L: ' + local + ', R: ' + remote)
self._asso_socket_map[conn_name] = sock
# If connection is established, we call connection handler
# in a new thread.
self._spawn(conn_name, conn_handler, sock)
return sock


Expand Down
7 changes: 6 additions & 1 deletion ryu/services/protocols/bgp/bgpspeaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CAP_MBGP_VPNV4
from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CAP_MBGP_VPNV6
from ryu.services.protocols.bgp.rtconf.neighbors import PEER_NEXT_HOP
from ryu.services.protocols.bgp.rtconf.neighbors import PASSWORD
from ryu.services.protocols.bgp.application import RyuBGPSpeaker


Expand Down Expand Up @@ -169,7 +170,7 @@ def neighbor_add(self, address, remote_as,
enable_ipv4=DEFAULT_CAP_MBGP_IPV4,
enable_vpnv4=DEFAULT_CAP_MBGP_VPNV4,
enable_vpnv6=DEFAULT_CAP_MBGP_VPNV6,
next_hop=None):
next_hop=None, password=None):
""" This method registers a new neighbor. The BGP speaker tries to
establish a bgp session with the peer (accepts a connection
from the peer and also tries to connect to it).
Expand All @@ -192,11 +193,15 @@ def neighbor_add(self, address, remote_as,
``next_hop`` specifies the next hop IP address. If not
specified, host's ip address to access to a peer is used.
``password`` is used for the MD5 authentication if it's
specified. By default, the MD5 authenticaiton is disabled.
"""
bgp_neighbor = {}
bgp_neighbor[neighbors.IP_ADDRESS] = address
bgp_neighbor[neighbors.REMOTE_AS] = remote_as
bgp_neighbor[PEER_NEXT_HOP] = next_hop
bgp_neighbor[PASSWORD] = password
# v6 advertizement is available with only v6 peering
if netaddr.valid_ipv4(address):
bgp_neighbor[CAP_MBGP_IPV4] = enable_ipv4
Expand Down
4 changes: 3 additions & 1 deletion ryu/services/protocols/bgp/peer.py
Original file line number Diff line number Diff line change
Expand Up @@ -822,10 +822,12 @@ def _connect_loop(self, client_factory):
LOG.debug('%s trying to connect to %s' % (self, peer_address))
tcp_conn_timeout = self._common_conf.tcp_conn_timeout
try:
password = self._neigh_conf.password
sock = self._connect_tcp(peer_address,
client_factory,
time_out=tcp_conn_timeout,
bind_address=bind_addr)
bind_address=bind_addr,
password=password)
except socket.error:
self.state.bgp_state = const.BGP_FSM_ACTIVE
LOG.debug('Socket could not be created in time (%s secs),'
Expand Down
15 changes: 14 additions & 1 deletion ryu/services/protocols/bgp/rtconf/neighbors.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
LOCAL_ADDRESS = 'local_address'
LOCAL_PORT = 'local_port'
PEER_NEXT_HOP = 'next_hop'
PASSWORD = 'password'

# Default value constants.
DEFAULT_CAP_GR_NULL = True
Expand Down Expand Up @@ -141,6 +142,11 @@ def validate_next_hop(ip_address):
return str(netaddr.IPAddress(ip_address))


@validate(name=PASSWORD)
def validate_password(password):
return password


@validate(name=LOCAL_PORT)
def validate_local_port(port):
if not isinstance(port, (int, long)):
Expand Down Expand Up @@ -174,7 +180,7 @@ class NeighborConf(ConfWithId, ConfWithStats):
ENABLED, MULTI_EXIT_DISC, MAX_PREFIXES,
ADVERTISE_PEER_AS, SITE_OF_ORIGINS,
LOCAL_ADDRESS, LOCAL_PORT,
PEER_NEXT_HOP])
PEER_NEXT_HOP, PASSWORD])

def __init__(self, **kwargs):
super(NeighborConf, self).__init__(**kwargs)
Expand Down Expand Up @@ -226,6 +232,9 @@ def _init_opt_settings(self, **kwargs):
self._settings[PEER_NEXT_HOP] = compute_optional_conf(
PEER_NEXT_HOP, None, **kwargs)

self._settings[PASSWORD] = compute_optional_conf(
PASSWORD, None, **kwargs)

# RTC configurations.
self._settings[CAP_RTC] = \
compute_optional_conf(CAP_RTC, DEFAULT_CAP_RTC, **kwargs)
Expand Down Expand Up @@ -282,6 +291,10 @@ def host_bind_port(self):
def next_hop(self):
return self._settings[PEER_NEXT_HOP]

@property
def password(self):
return self._settings[PASSWORD]

# =========================================================================
# Optional attributes with valid defaults.
# =========================================================================
Expand Down

0 comments on commit b984c15

Please sign in to comment.