summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-06-29 20:55:46 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-06-30 22:19:19 +0900
commitb984c15f68c24d32d974f3af90aa55db50e0246b (patch)
tree4013db17809ea67943b84ec229a8306c8ca72bd6
parent24220ea2e8c007f99e9e64934cfb865bd25d85d0 (diff)
bgp: support md5 authentication for pro-active sessions
For now, only Linux is supported. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/services/protocols/bgp/base.py33
-rw-r--r--ryu/services/protocols/bgp/bgpspeaker.py7
-rw-r--r--ryu/services/protocols/bgp/peer.py4
-rw-r--r--ryu/services/protocols/bgp/rtconf/neighbors.py15
4 files changed, 44 insertions, 15 deletions
diff --git a/ryu/services/protocols/bgp/base.py b/ryu/services/protocols/bgp/base.py
index e0338c26..87060cd6 100644
--- a/ryu/services/protocols/bgp/base.py
+++ b/ryu/services/protocols/bgp/base.py
@@ -24,6 +24,7 @@ import weakref
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
@@ -353,7 +354,7 @@ class Activity(object):
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
@@ -367,17 +368,25 @@ class Activity(object):
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
diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py
index 73bc72d4..aa851c53 100644
--- a/ryu/services/protocols/bgp/bgpspeaker.py
+++ b/ryu/services/protocols/bgp/bgpspeaker.py
@@ -51,6 +51,7 @@ from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CAP_MBGP_IPV4
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
@@ -169,7 +170,7 @@ class BGPSpeaker(object):
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).
@@ -192,11 +193,15 @@ class BGPSpeaker(object):
``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
diff --git a/ryu/services/protocols/bgp/peer.py b/ryu/services/protocols/bgp/peer.py
index 14838073..47f3c17b 100644
--- a/ryu/services/protocols/bgp/peer.py
+++ b/ryu/services/protocols/bgp/peer.py
@@ -822,10 +822,12 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
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),'
diff --git a/ryu/services/protocols/bgp/rtconf/neighbors.py b/ryu/services/protocols/bgp/rtconf/neighbors.py
index 1078e951..9ba57616 100644
--- a/ryu/services/protocols/bgp/rtconf/neighbors.py
+++ b/ryu/services/protocols/bgp/rtconf/neighbors.py
@@ -72,6 +72,7 @@ CHANGES = 'changes'
LOCAL_ADDRESS = 'local_address'
LOCAL_PORT = 'local_port'
PEER_NEXT_HOP = 'next_hop'
+PASSWORD = 'password'
# Default value constants.
DEFAULT_CAP_GR_NULL = True
@@ -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)):
@@ -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)
@@ -226,6 +232,9 @@ class NeighborConf(ConfWithId, ConfWithStats):
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)
@@ -282,6 +291,10 @@ class NeighborConf(ConfWithId, ConfWithStats):
def next_hop(self):
return self._settings[PEER_NEXT_HOP]
+ @property
+ def password(self):
+ return self._settings[PASSWORD]
+
# =========================================================================
# Optional attributes with valid defaults.
# =========================================================================