bgp: support specifying next hop for neighbor

neighbor_add method takes 'next_hop' parameter. If not specified, like
before, host's ip connected to the neighbor is used as a next hop.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
FUJITA Tomonori 2014-06-29 20:55:45 +09:00
parent f2e62c2f2b
commit bf58248a61
3 changed files with 28 additions and 3 deletions

View File

@ -50,6 +50,7 @@ from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6
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.application import RyuBGPSpeaker
@ -165,7 +166,8 @@ class BGPSpeaker(object):
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):
enable_vpnv6=DEFAULT_CAP_MBGP_VPNV6,
next_hop=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).
@ -186,10 +188,13 @@ class BGPSpeaker(object):
``enable_vpnv6`` enables VPNv6 address family for this
neighbor. The default is False.
``next_hop`` specifies the next hop IP address. If not
specified, host's ip address to access to a peer is used.
"""
bgp_neighbor = {}
bgp_neighbor[neighbors.IP_ADDRESS] = address
bgp_neighbor[neighbors.REMOTE_AS] = remote_as
bgp_neighbor[PEER_NEXT_HOP] = next_hop
# v6 advertizement is available with only v6 peering
if netaddr.valid_ipv4(address):
bgp_neighbor[CAP_MBGP_IPV4] = enable_ipv4

View File

@ -590,7 +590,10 @@ 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.host_bind_ip
if self._neigh_conf.next_hop:
next_hop = self._neigh_conf.next_hop
else:
next_hop = self.host_bind_ip
if route_family == RF_IPv6_VPN:
# Next hop ipv4_mapped ipv6
def _ipv4_mapped_ipv6(ipv4):

View File

@ -71,6 +71,7 @@ ENABLED = 'enabled'
CHANGES = 'changes'
LOCAL_ADDRESS = 'local_address'
LOCAL_PORT = 'local_port'
PEER_NEXT_HOP = 'next_hop'
# Default value constants.
DEFAULT_CAP_GR_NULL = True
@ -132,6 +133,14 @@ def validate_local_address(ip_address):
return str(netaddr.IPAddress(ip_address))
@validate(name=PEER_NEXT_HOP)
def validate_next_hop(ip_address):
if not valid_ip_address(ip_address):
raise ConfigValueError(desc='Invalid next_hop ip_address: %s' %
ip_address)
return str(netaddr.IPAddress(ip_address))
@validate(name=LOCAL_PORT)
def validate_local_port(port):
if not isinstance(port, (int, long)):
@ -164,7 +173,8 @@ class NeighborConf(ConfWithId, ConfWithStats):
CAP_RTC, RTC_AS, HOLD_TIME,
ENABLED, MULTI_EXIT_DISC, MAX_PREFIXES,
ADVERTISE_PEER_AS, SITE_OF_ORIGINS,
LOCAL_ADDRESS, LOCAL_PORT])
LOCAL_ADDRESS, LOCAL_PORT,
PEER_NEXT_HOP])
def __init__(self, **kwargs):
super(NeighborConf, self).__init__(**kwargs)
@ -213,6 +223,9 @@ class NeighborConf(ConfWithId, ConfWithStats):
self._settings[LOCAL_PORT] = compute_optional_conf(
LOCAL_PORT, None, **kwargs)
self._settings[PEER_NEXT_HOP] = compute_optional_conf(
PEER_NEXT_HOP, None, **kwargs)
# RTC configurations.
self._settings[CAP_RTC] = \
compute_optional_conf(CAP_RTC, DEFAULT_CAP_RTC, **kwargs)
@ -265,6 +278,10 @@ class NeighborConf(ConfWithId, ConfWithStats):
def host_bind_port(self):
return self._settings[LOCAL_PORT]
@property
def next_hop(self):
return self._settings[PEER_NEXT_HOP]
# =========================================================================
# Optional attributes with valid defaults.
# =========================================================================