diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2014-04-21 04:24:21 +0000 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-04-21 20:55:35 +0900 |
commit | 8b07123c91d337488e11cb72be84e4375669d9bb (patch) | |
tree | aaceebcac66719c89f5ca899784b1e2b10b902b4 | |
parent | ce33b61a1f07e9acee7b5b06a7062353299507de (diff) |
bgp: enable to use system IP addr implicitly for binding
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/services/protocols/bgp/base.py | 2 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/peer.py | 40 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/rtconf/neighbors.py | 21 |
3 files changed, 41 insertions, 22 deletions
diff --git a/ryu/services/protocols/bgp/base.py b/ryu/services/protocols/bgp/base.py index 24bb289f..77c8ef0b 100644 --- a/ryu/services/protocols/bgp/base.py +++ b/ryu/services/protocols/bgp/base.py @@ -351,7 +351,7 @@ class Activity(object): # If connection is established, we call connection handler # in a new thread. self._spawn(conn_name, conn_handler, sock) - + return sock # # Sink diff --git a/ryu/services/protocols/bgp/peer.py b/ryu/services/protocols/bgp/peer.py index 224dd8d3..7a11af14 100644 --- a/ryu/services/protocols/bgp/peer.py +++ b/ryu/services/protocols/bgp/peer.py @@ -278,6 +278,10 @@ class Peer(Source, Sink, NeighborConfListener, Activity): self._signal_bus = signal_bus self._peer_manager = peer_manager + # Host Bind IP + self._host_bind_ip = None + self._host_bind_port = None + # TODO(PH): revisit maintaining state/stats information. # Peer state. self.state = PeerState(self, self._signal_bus) @@ -331,6 +335,14 @@ class Peer(Source, Sink, NeighborConfListener, Activity): return self._neigh_conf.ip_address @property + def host_bind_ip(self): + return self._host_bind_ip + + @property + def host_bind_port(self): + return self._host_bind_port + + @property def enabled(self): return self._neigh_conf.enabled @@ -573,7 +585,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): point/local ip address. """ # By default we use BGPS's interface IP with this peer as next_hop. - next_hop = self._neigh_conf.host_bind_ip + next_hop = self.host_bind_ip if route_family == RF_IPv6_VPN: # Next hop ipv4_mapped ipv6 def _ipv4_mapped_ipv6(ipv4): @@ -617,7 +629,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # MP_REACH_NLRI Attribute. # By default we use BGPS's interface IP with this peer as next_hop. # TODO(PH): change to use protocol's local address. - # next_hop = self._neigh_conf.host_bind_ip + # next_hop = self.host_bind_ip next_hop = self._session_next_hop(path.route_family) # If this is a iBGP peer. if not self.is_ebgp_peer() and path.source is not None: @@ -790,19 +802,25 @@ class Peer(Source, Sink, NeighborConfListener, Activity): self.state.bgp_state = const.BGP_FSM_CONNECT # If we have specific host interface to bind to, we will do so # else we will bind to system default. - # Use current values. - bind_addr = (self._neigh_conf.host_bind_ip, - self._neigh_conf.host_bind_port) + if self._neigh_conf.host_bind_ip and \ + self._neigh_conf.host_bind_port: + bind_addr = (self._neigh_conf.host_bind_ip, + self._neigh_conf.host_bind_port) + else: + bind_addr = None peer_address = (self._neigh_conf.ip_address, const.STD_BGP_SERVER_PORT_NUM) LOG.debug('%s trying to connect to %s' % (self, peer_address)) tcp_conn_timeout = self._common_conf.tcp_conn_timeout try: - self._connect_tcp(peer_address, - client_factory, - time_out=tcp_conn_timeout, - bind_address=bind_addr) + sock = self._connect_tcp(peer_address, + client_factory, + time_out=tcp_conn_timeout, + bind_address=bind_addr) + bind_ip, bind_port = sock.getpeername() + self._host_bind_ip = bind_ip + self._host_bind_port = bind_port except socket.error: self.state.bgp_state = const.BGP_FSM_ACTIVE LOG.debug('Socket could not be created in time (%s secs),' @@ -1035,11 +1053,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # Validate Next hop. # TODO(PH): Currently ignore other cases. if (not mp_reach_attr.next_hop or - (mp_reach_attr.next_hop == self._neigh_conf.host_bind_ip)): + (mp_reach_attr.next_hop == self.host_bind_ip)): LOG.error('Nexthop of received UPDATE msg. (%s) same as local' ' interface address %s.' % (mp_reach_attr.next_hop, - self._neigh_conf.host_bind_ip)) + self.host_bind_ip)) return False return True diff --git a/ryu/services/protocols/bgp/rtconf/neighbors.py b/ryu/services/protocols/bgp/rtconf/neighbors.py index ab7fa482..8acd62ed 100644 --- a/ryu/services/protocols/bgp/rtconf/neighbors.py +++ b/ryu/services/protocols/bgp/rtconf/neighbors.py @@ -147,14 +147,14 @@ class NeighborConf(ConfWithId, ConfWithStats): UPDATE_MED_EVT = 'update_med_evt' VALID_EVT = frozenset([UPDATE_ENABLED_EVT, UPDATE_MED_EVT]) - REQUIRED_SETTINGS = frozenset([REMOTE_AS, IP_ADDRESS, LOCAL_ADDRESS, - LOCAL_PORT]) + REQUIRED_SETTINGS = frozenset([REMOTE_AS, IP_ADDRESS]) OPTIONAL_SETTINGS = frozenset([CAP_REFRESH, CAP_ENHANCED_REFRESH, CAP_MBGP_VPNV4, CAP_MBGP_IPV4, CAP_MBGP_VPNV6, CAP_RTC, RTC_AS, HOLD_TIME, ENABLED, MULTI_EXIT_DISC, MAX_PREFIXES, - ADVERTISE_PEER_AS, SITE_OF_ORIGINS]) + ADVERTISE_PEER_AS, SITE_OF_ORIGINS, + LOCAL_ADDRESS, LOCAL_PORT]) def __init__(self, **kwargs): super(NeighborConf, self).__init__(**kwargs) @@ -193,6 +193,14 @@ class NeighborConf(ConfWithId, ConfWithStats): if soos and validate_soo_list(soos): self._settings[SITE_OF_ORIGINS] = soos + # We do not have valid default LOCAL_ADDRESS and LOCAL_PORT value. + # If no LOCAL_ADDRESS/PORT is provided then we will bind to system + # default. + self._settings[LOCAL_ADDRESS] = compute_optional_conf( + LOCAL_ADDRESS, None, **kwargs) + self._settings[LOCAL_PORT] = compute_optional_conf( + LOCAL_PORT, None, **kwargs) + # RTC configurations. self._settings[CAP_RTC] = \ compute_optional_conf(CAP_RTC, DEFAULT_CAP_RTC, **kwargs) @@ -417,13 +425,6 @@ class NeighborsConf(BaseConf): message = 'Neighbor with given ip address already exists' raise RuntimeConfigError(desc=message) - # Check if this neighbor's host address overlaps with other neighbors - for nconf in self._neighbors.itervalues(): - if ((neigh_conf.host_bind_ip, neigh_conf.host_bind_port) == - (nconf.host_bind_ip, nconf.host_bind_port)): - raise RuntimeConfigError(desc='Given host_bind_ip and ' - 'host_bind_port already taken') - # Add this neighbor to known configured neighbors and generate update # event self._neighbors[neigh_conf.ip_address] = neigh_conf |