diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-06-29 20:55:46 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-06-30 22:19:19 +0900 |
commit | b984c15f68c24d32d974f3af90aa55db50e0246b (patch) | |
tree | 4013db17809ea67943b84ec229a8306c8ca72bd6 | |
parent | 24220ea2e8c007f99e9e64934cfb865bd25d85d0 (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.py | 33 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/bgpspeaker.py | 7 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/peer.py | 4 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/rtconf/neighbors.py | 15 |
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. # ========================================================================= |