bgp: support IPv6 peering
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
dabcfaa856
commit
3c3a29b535
@ -21,6 +21,7 @@ import socket
|
||||
import time
|
||||
import traceback
|
||||
import weakref
|
||||
import netaddr
|
||||
|
||||
from ryu.lib import hub
|
||||
from ryu.lib.hub import Timeout
|
||||
@ -318,16 +319,24 @@ class Activity(object):
|
||||
|
||||
For each connection `server_factory` starts a new protocol.
|
||||
"""
|
||||
server = hub.listen(loc_addr)
|
||||
if ':' in loc_addr[0]:
|
||||
server = hub.listen(loc_addr, family=socket.AF_INET6)
|
||||
else:
|
||||
server = hub.listen(loc_addr)
|
||||
|
||||
server_name = self.name + '_server@' + str(loc_addr)
|
||||
self._asso_socket_map[server_name] = server
|
||||
|
||||
# We now wait for connection requests from client.
|
||||
while True:
|
||||
sock, client_address = server.accept()
|
||||
client_address, port = client_address[:2]
|
||||
LOG.debug('Connect request received from client for port'
|
||||
' %s:%s' % client_address)
|
||||
client_name = self.name + '_client@' + str(client_address)
|
||||
' %s:%s' % (client_address, port))
|
||||
if 'ffff:' in client_address:
|
||||
client_address = str(netaddr.IPAddress(client_address).ipv4())
|
||||
|
||||
client_name = self.name + '_client@' + client_address
|
||||
self._asso_socket_map[client_name] = sock
|
||||
self._spawn(client_name, conn_handle, sock)
|
||||
|
||||
@ -341,8 +350,12 @@ class Activity(object):
|
||||
"""
|
||||
LOG.debug('Connect TCP called for %s:%s' % (peer_addr[0],
|
||||
peer_addr[1]))
|
||||
if netaddr.valid_ipv4(peer_addr[0]):
|
||||
family = socket.AF_INET
|
||||
else:
|
||||
family = socket.AF_INET6
|
||||
with Timeout(time_out, socket.error):
|
||||
sock = hub.connect(peer_addr, bind=bind_address)
|
||||
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
|
||||
|
@ -45,7 +45,7 @@ LOG = logging.getLogger('bgpspeaker.core')
|
||||
|
||||
# Interface IP address on which to run bgp server. Core service listens on all
|
||||
# interfaces of the host on port 179 - standard bgp port.
|
||||
CORE_IP = '0.0.0.0'
|
||||
CORE_IP = '::'
|
||||
|
||||
# Required dictates that Origin attribute be incomplete
|
||||
EXPECTED_ORIGIN = BGP_ATTR_ORIGIN_INCOMPLETE
|
||||
@ -380,7 +380,7 @@ class CoreService(Factory, Activity):
|
||||
def build_protocol(self, socket):
|
||||
assert socket
|
||||
# Check if its a reactive connection or pro-active connection
|
||||
_, remote_port = socket.getpeername()
|
||||
_, remote_port = socket.getpeername()[:2]
|
||||
is_reactive_conn = True
|
||||
if remote_port == STD_BGP_SERVER_PORT_NUM:
|
||||
is_reactive_conn = False
|
||||
@ -399,7 +399,9 @@ class CoreService(Factory, Activity):
|
||||
protocol.
|
||||
"""
|
||||
assert socket
|
||||
peer_addr, peer_port = socket.getpeername()
|
||||
peer_addr, peer_port = socket.getpeername()[:2]
|
||||
if 'ffff:' in peer_addr:
|
||||
peer_addr = str(netaddr.IPAddress(peer_addr).ipv4())
|
||||
peer = self._peer_manager.get_by_addr(peer_addr)
|
||||
bgp_proto = self.build_protocol(socket)
|
||||
|
||||
@ -424,7 +426,7 @@ class CoreService(Factory, Activity):
|
||||
subcode = BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION
|
||||
bgp_proto.send_notification(code, subcode)
|
||||
else:
|
||||
bind_ip, bind_port = socket.getsockname()
|
||||
bind_ip, bind_port = socket.getsockname()[0:2]
|
||||
peer._host_bind_ip = bind_ip
|
||||
peer._host_bind_port = bind_port
|
||||
self._spawn_activity(bgp_proto, peer)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import netaddr
|
||||
|
||||
from ryu.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF
|
||||
from ryu.services.protocols.bgp.model import OutgoingRoute
|
||||
@ -53,7 +54,7 @@ class PeerManager(object):
|
||||
self._core_service.on_peer_removed(peer)
|
||||
|
||||
def get_by_addr(self, addr):
|
||||
return self._peers.get(addr)
|
||||
return self._peers.get(str(netaddr.IPAddress(addr)))
|
||||
|
||||
def on_peer_down(self, peer):
|
||||
"""Peer down handler.
|
||||
|
@ -18,6 +18,7 @@
|
||||
"""
|
||||
from abc import abstractmethod
|
||||
import logging
|
||||
import netaddr
|
||||
|
||||
from ryu.lib.packet.bgp import RF_IPv4_UC
|
||||
from ryu.lib.packet.bgp import RF_IPv6_UC
|
||||
@ -107,20 +108,26 @@ def validate_changes(changes):
|
||||
return changes
|
||||
|
||||
|
||||
def valid_ip_address(addr):
|
||||
if not netaddr.valid_ipv4(addr) and not netaddr.valid_ipv6(addr):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@validate(name=IP_ADDRESS)
|
||||
def validate_ip_address(ip_address):
|
||||
if not is_valid_ipv4(ip_address):
|
||||
if not valid_ip_address(ip_address):
|
||||
raise ConfigValueError(desc='Invalid neighbor ip_address: %s' %
|
||||
ip_address)
|
||||
return ip_address
|
||||
return str(netaddr.IPAddress(ip_address))
|
||||
|
||||
|
||||
@validate(name=LOCAL_ADDRESS)
|
||||
def validate_local_address(ip_address):
|
||||
if not is_valid_ipv4(ip_address):
|
||||
if not valid_ip_address(ip_address):
|
||||
raise ConfigValueError(desc='Invalid local ip_address: %s' %
|
||||
ip_address)
|
||||
return ip_address
|
||||
return str(netaddr.IPAddress(ip_address))
|
||||
|
||||
|
||||
@validate(name=LOCAL_PORT)
|
||||
|
Loading…
x
Reference in New Issue
Block a user