summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSatoshi Fujimoto <satoshi.fujimoto7@gmail.com>2017-05-09 16:09:50 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-05-12 09:47:07 +0900
commit7e6c648ba1cb2a0e4567450dc0e90f063c6cf970 (patch)
treec9583888d909adfdda5b7402e37159aa2b4a8b33
parent4d9d444df1578026be1b8d4c30f2d1668c5117ee (diff)
BGPSpeaker: Support IPv6 Flow Spec update messages
Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/services/protocols/bgp/api/prefix.py6
-rw-r--r--ryu/services/protocols/bgp/base.py4
-rw-r--r--ryu/services/protocols/bgp/bgp_sample_conf.py85
-rw-r--r--ryu/services/protocols/bgp/bgpspeaker.py43
-rw-r--r--ryu/services/protocols/bgp/core_managers/table_manager.py79
-rw-r--r--ryu/services/protocols/bgp/model.py8
-rw-r--r--ryu/services/protocols/bgp/rtconf/base.py20
-rw-r--r--ryu/services/protocols/bgp/rtconf/neighbors.py29
-rw-r--r--ryu/services/protocols/bgp/rtconf/vrfs.py7
-rw-r--r--ryu/services/protocols/bgp/utils/bgp.py35
10 files changed, 302 insertions, 14 deletions
diff --git a/ryu/services/protocols/bgp/api/prefix.py b/ryu/services/protocols/bgp/api/prefix.py
index c169ed82..1a4207a1 100644
--- a/ryu/services/protocols/bgp/api/prefix.py
+++ b/ryu/services/protocols/bgp/api/prefix.py
@@ -27,7 +27,9 @@ from ryu.lib.packet.bgp import EvpnEthernetSegmentNLRI
from ryu.lib.packet.bgp import EvpnIpPrefixNLRI
from ryu.lib.packet.bgp import BGPPathAttributePmsiTunnel
from ryu.lib.packet.bgp import FlowSpecIPv4NLRI
+from ryu.lib.packet.bgp import FlowSpecIPv6NLRI
from ryu.lib.packet.bgp import FlowSpecVPNv4NLRI
+from ryu.lib.packet.bgp import FlowSpecVPNv6NLRI
from ryu.lib.packet.bgp import BGPFlowSpecTrafficRateCommunity
from ryu.lib.packet.bgp import BGPFlowSpecTrafficActionCommunity
from ryu.lib.packet.bgp import BGPFlowSpecRedirectCommunity
@@ -103,10 +105,14 @@ SUPPORTED_EVPN_ROUTE_TYPES = [
# Constants used in API calls for Flow Specification
FLOWSPEC_FAMILY_IPV4 = FlowSpecIPv4NLRI.FLOWSPEC_FAMILY
+FLOWSPEC_FAMILY_IPV6 = FlowSpecIPv6NLRI.FLOWSPEC_FAMILY
FLOWSPEC_FAMILY_VPNV4 = FlowSpecVPNv4NLRI.FLOWSPEC_FAMILY
+FLOWSPEC_FAMILY_VPNV6 = FlowSpecVPNv6NLRI.FLOWSPEC_FAMILY
SUPPORTED_FLOWSPEC_FAMILIES = (
FLOWSPEC_FAMILY_IPV4,
+ FLOWSPEC_FAMILY_IPV6,
FLOWSPEC_FAMILY_VPNV4,
+ FLOWSPEC_FAMILY_VPNV6,
)
# Constants for the Traffic Filtering Actions of Flow Specification
diff --git a/ryu/services/protocols/bgp/base.py b/ryu/services/protocols/bgp/base.py
index e5469020..0dc86079 100644
--- a/ryu/services/protocols/bgp/base.py
+++ b/ryu/services/protocols/bgp/base.py
@@ -37,7 +37,9 @@ from ryu.lib.packet.bgp import RF_IPv4_VPN
from ryu.lib.packet.bgp import RF_IPv6_VPN
from ryu.lib.packet.bgp import RF_L2_EVPN
from ryu.lib.packet.bgp import RF_IPv4_FLOWSPEC
+from ryu.lib.packet.bgp import RF_IPv6_FLOWSPEC
from ryu.lib.packet.bgp import RF_VPNv4_FLOWSPEC
+from ryu.lib.packet.bgp import RF_VPNv6_FLOWSPEC
from ryu.lib.packet.bgp import RF_RTC_UC
from ryu.services.protocols.bgp.utils.circlist import CircularListType
from ryu.services.protocols.bgp.utils.evtlet import LoopingCall
@@ -59,7 +61,9 @@ SUPPORTED_GLOBAL_RF = {
RF_IPv6_VPN,
RF_L2_EVPN,
RF_IPv4_FLOWSPEC,
+ RF_IPv6_FLOWSPEC,
RF_VPNv4_FLOWSPEC,
+ RF_VPNv6_FLOWSPEC,
}
diff --git a/ryu/services/protocols/bgp/bgp_sample_conf.py b/ryu/services/protocols/bgp/bgp_sample_conf.py
index 01afd489..3f34fbdc 100644
--- a/ryu/services/protocols/bgp/bgp_sample_conf.py
+++ b/ryu/services/protocols/bgp/bgp_sample_conf.py
@@ -4,6 +4,7 @@ from ryu.services.protocols.bgp.bgpspeaker import RF_VPN_V4
from ryu.services.protocols.bgp.bgpspeaker import RF_VPN_V6
from ryu.services.protocols.bgp.bgpspeaker import RF_L2_EVPN
from ryu.services.protocols.bgp.bgpspeaker import RF_VPNV4_FLOWSPEC
+from ryu.services.protocols.bgp.bgpspeaker import RF_VPNV6_FLOWSPEC
from ryu.services.protocols.bgp.bgpspeaker import EVPN_MAX_ET
from ryu.services.protocols.bgp.bgpspeaker import ESI_TYPE_LACP
from ryu.services.protocols.bgp.bgpspeaker import ESI_TYPE_MAC_BASED
@@ -14,7 +15,9 @@ from ryu.services.protocols.bgp.bgpspeaker import EVPN_MULTICAST_ETAG_ROUTE
from ryu.services.protocols.bgp.bgpspeaker import EVPN_ETH_SEGMENT
from ryu.services.protocols.bgp.bgpspeaker import EVPN_IP_PREFIX_ROUTE
from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_IPV4
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_IPV6
from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_VPNV4
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_VPNV6
from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_TA_SAMPLE
from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_TA_TERMINAL
from ryu.services.protocols.bgp.bgpspeaker import REDUNDANCY_MODE_SINGLE_ACTIVE
@@ -54,7 +57,9 @@ BGP = {
'address': '172.17.0.4',
'remote_as': 65001,
'enable_ipv4fs': True,
+ 'enable_ipv6fs': True,
'enable_vpnv4fs': True,
+ 'enable_vpnv6fs': True,
},
],
@@ -83,13 +88,20 @@ BGP = {
'export_rts': ['65001:200'],
'route_family': RF_L2_EVPN,
},
- # Example of VRF for FlowSpec
+ # Example of VRF for IPv4 FlowSpec
{
'route_dist': '65001:250',
'import_rts': ['65001:250'],
'export_rts': ['65001:250'],
'route_family': RF_VPNV4_FLOWSPEC,
},
+ # Example of VRF for IPv6 FlowSpec
+ {
+ 'route_dist': '65001:300',
+ 'import_rts': ['65001:300'],
+ 'export_rts': ['65001:300'],
+ 'route_family': RF_VPNV6_FLOWSPEC,
+ },
],
# List of BGP routes.
@@ -236,6 +248,77 @@ BGP = {
}
},
},
+ # Example of Flow Specification IPv6 prefix
+ {
+ 'flowspec_family': FLOWSPEC_FAMILY_IPV6,
+ 'rules': {
+ 'dst_prefix': '2001::1/128/32',
+ 'src_prefix': '3001::2/128',
+ 'next_header': 6,
+ 'port': '80 | 8000',
+ 'dst_port': '>9000 & <9050',
+ 'src_port': '>=8500 & <=9000',
+ 'icmp_type': 0,
+ 'icmp_code': 6,
+ 'tcp_flags': 'SYN+ACK & !=URGENT',
+ 'packet_len': 1000,
+ 'dscp': '22 | 24',
+ 'fragment': 'LF | ==FF',
+ 'flow_label': 100,
+ },
+ 'actions': {
+ 'traffic_rate': {
+ 'as_number': 0,
+ 'rate_info': 100.0,
+ },
+ 'traffic_action': {
+ 'action': FLOWSPEC_TA_SAMPLE | FLOWSPEC_TA_TERMINAL,
+ },
+ 'redirect': {
+ 'as_number': 10,
+ 'local_administrator': 100,
+ },
+ 'traffic_marking': {
+ 'dscp': 24,
+ }
+ },
+ },
+ # Example of Flow Specification VPNv6 prefix
+ {
+ 'flowspec_family': FLOWSPEC_FAMILY_VPNV6,
+ 'route_dist': '65001:300',
+ 'rules': {
+ 'dst_prefix': '2001::1/128/32',
+ 'src_prefix': '3001::2/128',
+ 'next_header': 6,
+ 'port': '80 | 8000',
+ 'dst_port': '>9000 & <9050',
+ 'src_port': '>=8500 & <=9000',
+ 'icmp_type': 0,
+ 'icmp_code': 6,
+ 'tcp_flags': 'SYN+ACK & !=URGENT',
+ 'packet_len': 1000,
+ 'dscp': '22 | 24',
+ 'fragment': 'LF | ==FF',
+ 'flow_label': 100,
+ },
+ 'actions': {
+ 'traffic_rate': {
+ 'as_number': 0,
+ 'rate_info': 100.0,
+ },
+ 'traffic_action': {
+ 'action': FLOWSPEC_TA_SAMPLE | FLOWSPEC_TA_TERMINAL,
+ },
+ 'redirect': {
+ 'as_number': 10,
+ 'local_administrator': 100,
+ },
+ 'traffic_marking': {
+ 'dscp': 24,
+ }
+ },
+ },
],
}
diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py
index 4965da87..3c8d6450 100644
--- a/ryu/services/protocols/bgp/bgpspeaker.py
+++ b/ryu/services/protocols/bgp/bgpspeaker.py
@@ -58,6 +58,8 @@ from ryu.services.protocols.bgp.api.prefix import (
FLOWSPEC_FAMILY,
FLOWSPEC_FAMILY_IPV4,
FLOWSPEC_FAMILY_VPNV4,
+ FLOWSPEC_FAMILY_IPV6,
+ FLOWSPEC_FAMILY_VPNV6,
FLOWSPEC_RULES,
FLOWSPEC_ACTIONS)
from ryu.services.protocols.bgp.rtconf.common import LOCAL_AS
@@ -82,18 +84,24 @@ from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_EVPN
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6FS
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6FS
from ryu.services.protocols.bgp.rtconf.base import CAP_ENHANCED_REFRESH
from ryu.services.protocols.bgp.rtconf.base import CAP_FOUR_OCTET_AS_NUMBER
from ryu.services.protocols.bgp.rtconf.base import MULTI_EXIT_DISC
from ryu.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS
-from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CAP_MBGP_IPV4
-from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CAP_MBGP_IPV6
-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 DEFAULT_CAP_MBGP_EVPN
-from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CAP_MBGP_IPV4FS
-from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CAP_MBGP_VPNV4FS
+from ryu.services.protocols.bgp.rtconf.neighbors import (
+ DEFAULT_CAP_MBGP_IPV4,
+ DEFAULT_CAP_MBGP_IPV6,
+ DEFAULT_CAP_MBGP_VPNV4,
+ DEFAULT_CAP_MBGP_VPNV6,
+ DEFAULT_CAP_MBGP_EVPN,
+ DEFAULT_CAP_MBGP_IPV4FS,
+ DEFAULT_CAP_MBGP_IPV6FS,
+ DEFAULT_CAP_MBGP_VPNV4FS,
+ DEFAULT_CAP_MBGP_VPNV6FS,
+)
from ryu.services.protocols.bgp.rtconf.neighbors import (
DEFAULT_CAP_ENHANCED_REFRESH, DEFAULT_CAP_FOUR_OCTET_AS_NUMBER)
from ryu.services.protocols.bgp.rtconf.neighbors import DEFAULT_CONNECT_MODE
@@ -122,6 +130,7 @@ RF_VPN_V4 = vrfs.VRF_RF_IPV4
RF_VPN_V6 = vrfs.VRF_RF_IPV6
RF_L2_EVPN = vrfs.VRF_RF_L2_EVPN
RF_VPNV4_FLOWSPEC = vrfs.VRF_RF_IPV4_FLOWSPEC
+RF_VPNV6_FLOWSPEC = vrfs.VRF_RF_IPV6_FLOWSPEC
# Constants for the Traffic Filtering Actions of Flow Specification.
FLOWSPEC_TA_SAMPLE = BGPFlowSpecTrafficActionCommunity.SAMPLE
@@ -354,7 +363,9 @@ class BGPSpeaker(object):
enable_vpnv6=DEFAULT_CAP_MBGP_VPNV6,
enable_evpn=DEFAULT_CAP_MBGP_EVPN,
enable_ipv4fs=DEFAULT_CAP_MBGP_IPV4FS,
+ enable_ipv6fs=DEFAULT_CAP_MBGP_IPV6FS,
enable_vpnv4fs=DEFAULT_CAP_MBGP_VPNV4FS,
+ enable_vpnv6fs=DEFAULT_CAP_MBGP_VPNV6FS,
enable_enhanced_refresh=DEFAULT_CAP_ENHANCED_REFRESH,
enable_four_octet_as_number=DEFAULT_CAP_FOUR_OCTET_AS_NUMBER,
next_hop=None, password=None, multi_exit_disc=None,
@@ -394,9 +405,15 @@ class BGPSpeaker(object):
``enable_ipv4fs`` enables IPv4 Flow Specification address family
for this neighbor.
+ ``enable_ipv6fs`` enables IPv6 Flow Specification address family
+ for this neighbor.
+
``enable_vpnv4fs`` enables VPNv4 Flow Specification address family
for this neighbor.
+ ``enable_vpnv6fs`` enables VPNv6 Flow Specification address family
+ for this neighbor.
+
``enable_enhanced_refresh`` enables Enhanced Route Refresh for this
neighbor.
@@ -457,7 +474,9 @@ class BGPSpeaker(object):
CAP_MBGP_VPNV6: enable_vpnv6,
CAP_MBGP_EVPN: enable_evpn,
CAP_MBGP_IPV4FS: enable_ipv4fs,
+ CAP_MBGP_IPV6FS: enable_ipv6fs,
CAP_MBGP_VPNV4FS: enable_vpnv4fs,
+ CAP_MBGP_VPNV6FS: enable_vpnv6fs,
}
if multi_exit_disc:
@@ -821,7 +840,9 @@ class BGPSpeaker(object):
This parameter must be one of the following.
- FLOWSPEC_FAMILY_IPV4 = 'ipv4fs'
+ - FLOWSPEC_FAMILY_IPV6 = 'ipv6fs'
- FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
+ - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
``rules`` specifies NLRIs of Flow Specification as
a dictionary type value.
@@ -829,13 +850,16 @@ class BGPSpeaker(object):
see `from_user()` method of the following classes.
- :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv4NLRI`
+ - :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv6NLRI`
- :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv4NLRI`
+ - :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv6NLRI`
``route_dist`` specifies a route distinguisher value.
This parameter is required only if flowspec_family is one of the
following address family.
- FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
+ - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
``actions`` specifies Traffic Filtering Actions of
Flow Specification as a dictionary type value.
@@ -903,7 +927,7 @@ class BGPSpeaker(object):
FLOWSPEC_ACTIONS: actions or {},
}
- if flowspec_family == FLOWSPEC_FAMILY_VPNV4:
+ if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6]:
func_name = 'flowspec.add_local'
kwargs.update({ROUTE_DISTINGUISHER: route_dist})
@@ -927,7 +951,7 @@ class BGPSpeaker(object):
FLOWSPEC_RULES: rules,
}
- if flowspec_family == FLOWSPEC_FAMILY_VPNV4:
+ if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6]:
func_name = 'flowspec.del_local'
kwargs.update({ROUTE_DISTINGUISHER: route_dist})
@@ -953,6 +977,7 @@ class BGPSpeaker(object):
- RF_VPN_V6 = 'ipv6'
- RF_L2_EVPN = 'evpn'
- RF_VPNV4_FLOWSPEC = 'ipv4fs'
+ - RF_VPNV6_FLOWSPEC = 'ipv6fs'
``multi_exit_disc`` specifies multi exit discriminator (MED) value.
It must be an integer.
diff --git a/ryu/services/protocols/bgp/core_managers/table_manager.py b/ryu/services/protocols/bgp/core_managers/table_manager.py
index 297b7a41..27e0bd31 100644
--- a/ryu/services/protocols/bgp/core_managers/table_manager.py
+++ b/ryu/services/protocols/bgp/core_managers/table_manager.py
@@ -19,12 +19,18 @@ from ryu.services.protocols.bgp.info_base.ipv4fs import IPv4FlowSpecPath
from ryu.services.protocols.bgp.info_base.ipv4fs import IPv4FlowSpecTable
from ryu.services.protocols.bgp.info_base.vpnv4fs import VPNv4FlowSpecTable
from ryu.services.protocols.bgp.info_base.vrf4fs import Vrf4FlowSpecTable
+from ryu.services.protocols.bgp.info_base.ipv6fs import IPv6FlowSpecPath
+from ryu.services.protocols.bgp.info_base.ipv6fs import IPv6FlowSpecTable
+from ryu.services.protocols.bgp.info_base.vpnv6fs import VPNv6FlowSpecTable
+from ryu.services.protocols.bgp.info_base.vrf6fs import Vrf6FlowSpecTable
from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4
from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV6
from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_L2_EVPN
from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4_FLOWSPEC
+from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV6_FLOWSPEC
from ryu.services.protocols.bgp.rtconf.vrfs import SUPPORTED_VRF_RF
from ryu.services.protocols.bgp.utils.bgp import create_v4flowspec_actions
+from ryu.services.protocols.bgp.utils.bgp import create_v6flowspec_actions
from ryu.lib import type_desc
from ryu.lib.packet.bgp import RF_IPv4_UC
@@ -33,7 +39,9 @@ from ryu.lib.packet.bgp import RF_IPv4_VPN
from ryu.lib.packet.bgp import RF_IPv6_VPN
from ryu.lib.packet.bgp import RF_L2_EVPN
from ryu.lib.packet.bgp import RF_IPv4_FLOWSPEC
+from ryu.lib.packet.bgp import RF_IPv6_FLOWSPEC
from ryu.lib.packet.bgp import RF_VPNv4_FLOWSPEC
+from ryu.lib.packet.bgp import RF_VPNv6_FLOWSPEC
from ryu.lib.packet.bgp import RF_RTC_UC
from ryu.lib.packet.bgp import BGPPathAttributeOrigin
from ryu.lib.packet.bgp import BGPPathAttributeAsPath
@@ -50,6 +58,7 @@ from ryu.lib.packet.bgp import EvpnInclusiveMulticastEthernetTagNLRI
from ryu.lib.packet.bgp import IPAddrPrefix
from ryu.lib.packet.bgp import IP6AddrPrefix
from ryu.lib.packet.bgp import FlowSpecIPv4NLRI
+from ryu.lib.packet.bgp import FlowSpecIPv6NLRI
from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4
from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4_prefix
@@ -132,6 +141,8 @@ class TableCoreManager(object):
vpn_table = self.get_evpn_table()
elif vrf_table.route_family == Vrf4FlowSpecTable.ROUTE_FAMILY:
vpn_table = self.get_vpnv4fs_table()
+ elif vrf_table.route_family == Vrf6FlowSpecTable.ROUTE_FAMILY:
+ vpn_table = self.get_vpnv6fs_table()
else:
raise ValueError('Invalid VRF table route family: %s' %
vrf_table.route_family)
@@ -200,8 +211,12 @@ class TableCoreManager(object):
global_table = self.get_evpn_table()
elif route_family == RF_IPv4_FLOWSPEC:
global_table = self.get_ipv4fs_table()
+ elif route_family == RF_IPv6_FLOWSPEC:
+ global_table = self.get_ipv6fs_table()
elif route_family == RF_VPNv4_FLOWSPEC:
global_table = self.get_vpnv4fs_table()
+ elif route_family == RF_VPNv6_FLOWSPEC:
+ global_table = self.get_vpnv6fs_table()
elif route_family == RF_RTC_UC:
global_table = self.get_rtc_table()
@@ -327,6 +342,21 @@ class TableCoreManager(object):
return ipv4fs_table
+ def get_ipv6fs_table(self):
+ """Returns global IPv6 Flow Specification table.
+
+ Creates the table if it does not exist.
+ """
+ ipv6fs_table = self._global_tables.get(RF_IPv6_FLOWSPEC)
+ # Lazy initialization of the table.
+ if not ipv6fs_table:
+ ipv6fs_table = IPv6FlowSpecTable(self._core_service,
+ self._signal_bus)
+ self._global_tables[RF_IPv6_FLOWSPEC] = ipv6fs_table
+ self._tables[(None, RF_IPv6_FLOWSPEC)] = ipv6fs_table
+
+ return ipv6fs_table
+
def get_vpnv4fs_table(self):
"""Returns global VPNv4 Flow Specification table.
@@ -342,6 +372,21 @@ class TableCoreManager(object):
return vpnv4fs_table
+ def get_vpnv6fs_table(self):
+ """Returns global VPNv6 Flow Specification table.
+
+ Creates the table if it does not exist.
+ """
+ vpnv6fs_table = self._global_tables.get(RF_VPNv6_FLOWSPEC)
+ # Lazy initialization of the table.
+ if not vpnv6fs_table:
+ vpnv6fs_table = VPNv6FlowSpecTable(self._core_service,
+ self._signal_bus)
+ self._global_tables[RF_VPNv6_FLOWSPEC] = vpnv6fs_table
+ self._tables[(None, RF_VPNv6_FLOWSPEC)] = vpnv6fs_table
+
+ return vpnv6fs_table
+
def get_nexthop_label(self, label_key):
return self._next_hop_label.get(label_key, None)
@@ -423,6 +468,8 @@ class TableCoreManager(object):
vrf_table = VrfEvpnTable
elif route_family == VRF_RF_IPV4_FLOWSPEC:
vrf_table = Vrf4FlowSpecTable
+ elif route_family == VRF_RF_IPV6_FLOWSPEC:
+ vrf_table = Vrf6FlowSpecTable
else:
raise ValueError('Unsupported route family for VRF: %s' %
route_family)
@@ -508,6 +555,8 @@ class TableCoreManager(object):
route_family = RF_L2_EVPN
elif vpn_path.route_family == RF_VPNv4_FLOWSPEC:
route_family = RF_IPv4_FLOWSPEC
+ elif vpn_path.route_family == RF_VPNv6_FLOWSPEC:
+ route_family = RF_IPv6_FLOWSPEC
else:
raise ValueError('Unsupported route family for VRF: %s' %
vpn_path.route_family)
@@ -650,7 +699,10 @@ class TableCoreManager(object):
If `is_withdraw` is True, remove a BGP route from the VRF table.
"""
from ryu.services.protocols.bgp.core import BgpCoreError
- from ryu.services.protocols.bgp.api.prefix import FLOWSPEC_FAMILY_VPNV4
+ from ryu.services.protocols.bgp.api.prefix import (
+ FLOWSPEC_FAMILY_VPNV4,
+ FLOWSPEC_FAMILY_VPNV6,
+ )
if flowspec_family == FLOWSPEC_FAMILY_VPNV4:
vrf_table = self._tables.get((route_dist, VRF_RF_IPV4_FLOWSPEC))
@@ -659,6 +711,13 @@ class TableCoreManager(object):
communities = create_v4flowspec_actions(actions)
except ValueError as e:
raise BgpCoreError(desc=str(e))
+ elif flowspec_family == FLOWSPEC_FAMILY_VPNV6:
+ vrf_table = self._tables.get((route_dist, VRF_RF_IPV6_FLOWSPEC))
+ prefix = FlowSpecIPv6NLRI.from_user(**rules)
+ try:
+ communities = create_v6flowspec_actions(actions)
+ except ValueError as e:
+ raise BgpCoreError(desc=str(e))
else:
raise BgpCoreError(
desc='Unsupported flowspec_family %s' % flowspec_family)
@@ -732,7 +791,10 @@ class TableCoreManager(object):
"""
from ryu.services.protocols.bgp.core import BgpCoreError
- from ryu.services.protocols.bgp.api.prefix import FLOWSPEC_FAMILY_IPV4
+ from ryu.services.protocols.bgp.api.prefix import (
+ FLOWSPEC_FAMILY_IPV4,
+ FLOWSPEC_FAMILY_IPV6,
+ )
src_ver_num = 1
peer = None
@@ -758,6 +820,19 @@ class TableCoreManager(object):
pathattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = (
BGPPathAttributeExtendedCommunities(
communities=communities))
+ elif flowspec_family == FLOWSPEC_FAMILY_IPV6:
+ _nlri = FlowSpecIPv6NLRI.from_user(**rules)
+ p = IPv6FlowSpecPath
+
+ try:
+ communities = create_v6flowspec_actions(actions)
+ except ValueError as e:
+ raise BgpCoreError(desc=str(e))
+
+ if communities:
+ pathattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = (
+ BGPPathAttributeExtendedCommunities(
+ communities=communities))
else:
raise BgpCoreError(
desc='Unsupported flowspec family %s' % flowspec_family)
diff --git a/ryu/services/protocols/bgp/model.py b/ryu/services/protocols/bgp/model.py
index 67391397..faa33f04 100644
--- a/ryu/services/protocols/bgp/model.py
+++ b/ryu/services/protocols/bgp/model.py
@@ -97,11 +97,15 @@ class FlexinetOutgoingRoute(object):
from ryu.services.protocols.bgp.info_base.vrf4 import Vrf4Path
from ryu.services.protocols.bgp.info_base.vrf6 import Vrf6Path
from ryu.services.protocols.bgp.info_base.vrfevpn import VrfEvpnPath
- from ryu.services.protocols.bgp.info_base.vrf4fs import Vrf4FlowSpecPath
+ from ryu.services.protocols.bgp.info_base.vrf4fs import (
+ Vrf4FlowSpecPath)
+ from ryu.services.protocols.bgp.info_base.vrf6fs import (
+ Vrf6FlowSpecPath)
assert path.route_family in (Vrf4Path.ROUTE_FAMILY,
Vrf6Path.ROUTE_FAMILY,
VrfEvpnPath.ROUTE_FAMILY,
- Vrf4FlowSpecPath.ROUTE_FAMILY)
+ Vrf4FlowSpecPath.ROUTE_FAMILY,
+ Vrf6FlowSpecPath.ROUTE_FAMILY)
self.sink = None
self._path = path
diff --git a/ryu/services/protocols/bgp/rtconf/base.py b/ryu/services/protocols/bgp/rtconf/base.py
index bdd43091..d839d385 100644
--- a/ryu/services/protocols/bgp/rtconf/base.py
+++ b/ryu/services/protocols/bgp/rtconf/base.py
@@ -47,7 +47,9 @@ CAP_MBGP_VPNV4 = 'cap_mbgp_vpnv4'
CAP_MBGP_VPNV6 = 'cap_mbgp_vpnv6'
CAP_MBGP_EVPN = 'cap_mbgp_evpn'
CAP_MBGP_IPV4FS = 'cap_mbgp_ipv4fs'
+CAP_MBGP_IPV6FS = 'cap_mbgp_ipv6fs'
CAP_MBGP_VPNV4FS = 'cap_mbgp_vpnv4fs'
+CAP_MBGP_VPNV6FS = 'cap_mbgp_vpnv6fs'
CAP_RTC = 'cap_rtc'
RTC_AS = 'rtc_as'
HOLD_TIME = 'hold_time'
@@ -659,6 +661,15 @@ def validate_cap_mbgp_ipv4fs(cmv4fs):
return cmv4fs
+@validate(name=CAP_MBGP_IPV6FS)
+def validate_cap_mbgp_ipv6fs(cmv6fs):
+ if not isinstance(cmv6fs, bool):
+ raise ConfigTypeError(desc='Invalid MP-BGP '
+ 'IPv6 Flow Specification capability '
+ 'settings: %s. Boolean value expected' % cmv6fs)
+ return cmv6fs
+
+
@validate(name=CAP_MBGP_VPNV4FS)
def validate_cap_mbgp_vpnv4fs(cmv4fs):
if not isinstance(cmv4fs, bool):
@@ -668,6 +679,15 @@ def validate_cap_mbgp_vpnv4fs(cmv4fs):
return cmv4fs
+@validate(name=CAP_MBGP_VPNV6FS)
+def validate_cap_mbgp_vpnv66fs(cmv6fs):
+ if not isinstance(cmv6fs, bool):
+ raise ConfigTypeError(desc='Invalid MP-BGP '
+ 'VPNv6 Flow Specification capability '
+ 'settings: %s. Boolean value expected' % cmv6fs)
+ return cmv6fs
+
+
@validate(name=CAP_RTC)
def validate_cap_rtc(cap_rtc):
if not isinstance(cap_rtc, bool):
diff --git a/ryu/services/protocols/bgp/rtconf/neighbors.py b/ryu/services/protocols/bgp/rtconf/neighbors.py
index 987d4da0..d99e509a 100644
--- a/ryu/services/protocols/bgp/rtconf/neighbors.py
+++ b/ryu/services/protocols/bgp/rtconf/neighbors.py
@@ -28,7 +28,9 @@ from ryu.lib.packet.bgp import RF_IPv4_VPN
from ryu.lib.packet.bgp import RF_IPv6_VPN
from ryu.lib.packet.bgp import RF_L2_EVPN
from ryu.lib.packet.bgp import RF_IPv4_FLOWSPEC
+from ryu.lib.packet.bgp import RF_IPv6_FLOWSPEC
from ryu.lib.packet.bgp import RF_VPNv4_FLOWSPEC
+from ryu.lib.packet.bgp import RF_VPNv6_FLOWSPEC
from ryu.lib.packet.bgp import RF_RTC_UC
from ryu.lib.packet.bgp import BGPOptParamCapabilityFourOctetAsNumber
from ryu.lib.packet.bgp import BGPOptParamCapabilityEnhancedRouteRefresh
@@ -51,7 +53,9 @@ from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_EVPN
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6FS
from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6FS
from ryu.services.protocols.bgp.rtconf.base import CAP_REFRESH
from ryu.services.protocols.bgp.rtconf.base import CAP_RTC
from ryu.services.protocols.bgp.rtconf.base import compute_optional_conf
@@ -110,7 +114,9 @@ DEFAULT_CAP_MBGP_VPNV4 = False
DEFAULT_CAP_MBGP_VPNV6 = False
DEFAULT_CAP_MBGP_EVPN = False
DEFAULT_CAP_MBGP_IPV4FS = False
+DEFAULT_CAP_MBGP_IPV6FS = False
DEFAULT_CAP_MBGP_VPNV4FS = False
+DEFAULT_CAP_MBGP_VPNV6FS = False
DEFAULT_HOLD_TIME = 40
DEFAULT_ENABLED = True
DEFAULT_CAP_RTC = False
@@ -325,6 +331,7 @@ class NeighborConf(ConfWithId, ConfWithStats):
CAP_MBGP_VPNV4, CAP_MBGP_VPNV6,
CAP_RTC, CAP_MBGP_EVPN,
CAP_MBGP_IPV4FS, CAP_MBGP_VPNV4FS,
+ CAP_MBGP_IPV6FS, CAP_MBGP_VPNV6FS,
RTC_AS, HOLD_TIME,
ENABLED, MULTI_EXIT_DISC, MAX_PREFIXES,
ADVERTISE_PEER_AS, SITE_OF_ORIGINS,
@@ -359,8 +366,12 @@ class NeighborConf(ConfWithId, ConfWithStats):
CAP_MBGP_VPNV6, DEFAULT_CAP_MBGP_VPNV6, **kwargs)
self._settings[CAP_MBGP_IPV4FS] = compute_optional_conf(
CAP_MBGP_IPV4FS, DEFAULT_CAP_MBGP_IPV4FS, **kwargs)
+ self._settings[CAP_MBGP_IPV6FS] = compute_optional_conf(
+ CAP_MBGP_IPV6FS, DEFAULT_CAP_MBGP_IPV6FS, **kwargs)
self._settings[CAP_MBGP_VPNV4FS] = compute_optional_conf(
CAP_MBGP_VPNV4FS, DEFAULT_CAP_MBGP_VPNV4FS, **kwargs)
+ self._settings[CAP_MBGP_VPNV6FS] = compute_optional_conf(
+ CAP_MBGP_VPNV6FS, DEFAULT_CAP_MBGP_VPNV6FS, **kwargs)
self._settings[HOLD_TIME] = compute_optional_conf(
HOLD_TIME, DEFAULT_HOLD_TIME, **kwargs)
self._settings[ENABLED] = compute_optional_conf(
@@ -535,10 +546,18 @@ class NeighborConf(ConfWithId, ConfWithStats):
return self._settings[CAP_MBGP_IPV4FS]
@property
+ def cap_mbgp_ipv6fs(self):
+ return self._settings[CAP_MBGP_IPV6FS]
+
+ @property
def cap_mbgp_vpnv4fs(self):
return self._settings[CAP_MBGP_VPNV4FS]
@property
+ def cap_mbgp_vpnv6fs(self):
+ return self._settings[CAP_MBGP_VPNV6FS]
+
+ @property
def cap_rtc(self):
return self._settings[CAP_RTC]
@@ -667,11 +686,21 @@ class NeighborConf(ConfWithId, ConfWithStats):
BGPOptParamCapabilityMultiprotocol(
RF_IPv4_FLOWSPEC.afi, RF_IPv4_FLOWSPEC.safi))
+ if self.cap_mbgp_ipv6fs:
+ mbgp_caps.append(
+ BGPOptParamCapabilityMultiprotocol(
+ RF_IPv6_FLOWSPEC.afi, RF_IPv6_FLOWSPEC.safi))
+
if self.cap_mbgp_vpnv4fs:
mbgp_caps.append(
BGPOptParamCapabilityMultiprotocol(
RF_VPNv4_FLOWSPEC.afi, RF_VPNv4_FLOWSPEC.safi))
+ if self.cap_mbgp_vpnv6fs:
+ mbgp_caps.append(
+ BGPOptParamCapabilityMultiprotocol(
+ RF_VPNv6_FLOWSPEC.afi, RF_VPNv6_FLOWSPEC.safi))
+
if mbgp_caps:
capabilities[BGP_CAP_MULTIPROTOCOL] = mbgp_caps
diff --git a/ryu/services/protocols/bgp/rtconf/vrfs.py b/ryu/services/protocols/bgp/rtconf/vrfs.py
index 9106a0de..a918c5b9 100644
--- a/ryu/services/protocols/bgp/rtconf/vrfs.py
+++ b/ryu/services/protocols/bgp/rtconf/vrfs.py
@@ -24,6 +24,7 @@ from ryu.lib.packet.bgp import RF_IPv4_UC
from ryu.lib.packet.bgp import RF_IPv6_UC
from ryu.lib.packet.bgp import RF_L2_EVPN
from ryu.lib.packet.bgp import RF_IPv4_FLOWSPEC
+from ryu.lib.packet.bgp import RF_IPv6_FLOWSPEC
from ryu.services.protocols.bgp.utils import validation
from ryu.services.protocols.bgp.base import get_validator
@@ -61,11 +62,13 @@ VRF_RF_IPV4 = 'ipv4'
VRF_RF_IPV6 = 'ipv6'
VRF_RF_L2_EVPN = 'evpn'
VRF_RF_IPV4_FLOWSPEC = 'ipv4fs'
+VRF_RF_IPV6_FLOWSPEC = 'ipv6fs'
SUPPORTED_VRF_RF = (
VRF_RF_IPV4,
VRF_RF_IPV6,
VRF_RF_L2_EVPN,
VRF_RF_IPV4_FLOWSPEC,
+ VRF_RF_IPV6_FLOWSPEC,
)
@@ -235,6 +238,8 @@ class VrfConf(ConfWithId, ConfWithStats):
return RF_L2_EVPN
elif vrf_rf == VRF_RF_IPV4_FLOWSPEC:
return RF_IPv4_FLOWSPEC
+ elif vrf_rf == VRF_RF_IPV6_FLOWSPEC:
+ return RF_IPv6_FLOWSPEC
else:
raise ValueError('Unsupported VRF route family given %s' % vrf_rf)
@@ -248,6 +253,8 @@ class VrfConf(ConfWithId, ConfWithStats):
return VRF_RF_L2_EVPN
elif route_family == RF_IPv4_FLOWSPEC:
return VRF_RF_IPV4_FLOWSPEC
+ elif route_family == RF_IPv6_FLOWSPEC:
+ return VRF_RF_IPV6_FLOWSPEC
else:
raise ValueError('No supported mapping for route family '
'to vrf_route_family exists for %s' %
diff --git a/ryu/services/protocols/bgp/utils/bgp.py b/ryu/services/protocols/bgp/utils/bgp.py
index 5aa2012d..2d066944 100644
--- a/ryu/services/protocols/bgp/utils/bgp.py
+++ b/ryu/services/protocols/bgp/utils/bgp.py
@@ -29,7 +29,9 @@ from ryu.lib.packet.bgp import (
RF_IPv6_VPN,
RF_L2_EVPN,
RF_IPv4_FLOWSPEC,
+ RF_IPv6_FLOWSPEC,
RF_VPNv4_FLOWSPEC,
+ RF_VPNv6_FLOWSPEC,
RF_RTC_UC,
RouteTargetMembershipNLRI,
BGP_ATTR_TYPE_MULTI_EXIT_DISC,
@@ -55,7 +57,9 @@ from ryu.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path
from ryu.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path
from ryu.services.protocols.bgp.info_base.evpn import EvpnPath
from ryu.services.protocols.bgp.info_base.ipv4fs import IPv4FlowSpecPath
+from ryu.services.protocols.bgp.info_base.ipv6fs import IPv6FlowSpecPath
from ryu.services.protocols.bgp.info_base.vpnv4fs import VPNv4FlowSpecPath
+from ryu.services.protocols.bgp.info_base.vpnv6fs import VPNv6FlowSpecPath
LOG = logging.getLogger('utils.bgp')
@@ -67,7 +71,9 @@ _ROUTE_FAMILY_TO_PATH_MAP = {RF_IPv4_UC: Ipv4Path,
RF_IPv6_VPN: Vpnv6Path,
RF_L2_EVPN: EvpnPath,
RF_IPv4_FLOWSPEC: IPv4FlowSpecPath,
+ RF_IPv6_FLOWSPEC: IPv6FlowSpecPath,
RF_VPNv4_FLOWSPEC: VPNv4FlowSpecPath,
+ RF_VPNv6_FLOWSPEC: VPNv6FlowSpecPath,
RF_RTC_UC: RtcPath}
@@ -215,6 +221,35 @@ def create_v4flowspec_actions(actions=None):
FLOWSPEC_ACTION_TRAFFIC_MARKING: BGPFlowSpecTrafficMarkingCommunity,
}
+ return _create_actions(actions, action_types)
+
+
+def create_v6flowspec_actions(actions=None):
+ """
+ Create list of traffic filtering actions
+ for Ipv6 Flow Specification and VPNv6 Flow Specification.
+
+ "FLOWSPEC_ACTION_REDIRECT_IPV6" is not implemented yet.
+ """
+ from ryu.services.protocols.bgp.api.prefix import (
+ FLOWSPEC_ACTION_TRAFFIC_RATE,
+ FLOWSPEC_ACTION_TRAFFIC_ACTION,
+ FLOWSPEC_ACTION_REDIRECT,
+ FLOWSPEC_ACTION_TRAFFIC_MARKING,
+ )
+
+ # Supported action type for IPv6 and VPNv6.
+ action_types = {
+ FLOWSPEC_ACTION_TRAFFIC_RATE: BGPFlowSpecTrafficRateCommunity,
+ FLOWSPEC_ACTION_TRAFFIC_ACTION: BGPFlowSpecTrafficActionCommunity,
+ FLOWSPEC_ACTION_REDIRECT: BGPFlowSpecRedirectCommunity,
+ FLOWSPEC_ACTION_TRAFFIC_MARKING: BGPFlowSpecTrafficMarkingCommunity,
+ }
+
+ return _create_actions(actions, action_types)
+
+
+def _create_actions(actions, action_types):
communities = []
if actions is None: