summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSatoshi Fujimoto <satoshi.fujimoto7@gmail.com>2017-05-09 16:09:59 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-05-12 09:48:14 +0900
commit0168c289357c503f0b03fae84afa87a0b6c2464c (patch)
tree066e1cfe7c0cb994c747dc52225cc1d770b6111f
parent0b9bc03e6c3a543ad9a4f644b15ace1d777deefb (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.py9
-rw-r--r--ryu/services/protocols/bgp/base.py2
-rw-r--r--ryu/services/protocols/bgp/bgp_sample_conf.py64
-rw-r--r--ryu/services/protocols/bgp/bgpspeaker.py38
-rw-r--r--ryu/services/protocols/bgp/core_managers/table_manager.py52
-rw-r--r--ryu/services/protocols/bgp/info_base/vrf.py11
-rw-r--r--ryu/services/protocols/bgp/model.py6
-rw-r--r--ryu/services/protocols/bgp/rtconf/base.py10
-rw-r--r--ryu/services/protocols/bgp/rtconf/neighbors.py15
-rw-r--r--ryu/services/protocols/bgp/rtconf/vrfs.py7
-rw-r--r--ryu/services/protocols/bgp/utils/bgp.py31
11 files changed, 237 insertions, 8 deletions
diff --git a/ryu/services/protocols/bgp/api/prefix.py b/ryu/services/protocols/bgp/api/prefix.py
index 1a4207a1..c3e42622 100644
--- a/ryu/services/protocols/bgp/api/prefix.py
+++ b/ryu/services/protocols/bgp/api/prefix.py
@@ -30,10 +30,13 @@ 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 FlowSpecL2VPNNLRI
from ryu.lib.packet.bgp import BGPFlowSpecTrafficRateCommunity
from ryu.lib.packet.bgp import BGPFlowSpecTrafficActionCommunity
from ryu.lib.packet.bgp import BGPFlowSpecRedirectCommunity
from ryu.lib.packet.bgp import BGPFlowSpecTrafficMarkingCommunity
+from ryu.lib.packet.bgp import BGPFlowSpecVlanActionCommunity
+from ryu.lib.packet.bgp import BGPFlowSpecTPIDActionCommunity
from ryu.services.protocols.bgp.api.base import EVPN_ROUTE_TYPE
from ryu.services.protocols.bgp.api.base import EVPN_ESI
@@ -108,11 +111,13 @@ FLOWSPEC_FAMILY_IPV4 = FlowSpecIPv4NLRI.FLOWSPEC_FAMILY
FLOWSPEC_FAMILY_IPV6 = FlowSpecIPv6NLRI.FLOWSPEC_FAMILY
FLOWSPEC_FAMILY_VPNV4 = FlowSpecVPNv4NLRI.FLOWSPEC_FAMILY
FLOWSPEC_FAMILY_VPNV6 = FlowSpecVPNv6NLRI.FLOWSPEC_FAMILY
+FLOWSPEC_FAMILY_L2VPN = FlowSpecL2VPNNLRI.FLOWSPEC_FAMILY
SUPPORTED_FLOWSPEC_FAMILIES = (
FLOWSPEC_FAMILY_IPV4,
FLOWSPEC_FAMILY_IPV6,
FLOWSPEC_FAMILY_VPNV4,
FLOWSPEC_FAMILY_VPNV6,
+ FLOWSPEC_FAMILY_L2VPN,
)
# Constants for the Traffic Filtering Actions of Flow Specification
@@ -121,12 +126,16 @@ FLOWSPEC_ACTION_TRAFFIC_RATE = BGPFlowSpecTrafficRateCommunity.ACTION_NAME
FLOWSPEC_ACTION_TRAFFIC_ACTION = BGPFlowSpecTrafficActionCommunity.ACTION_NAME
FLOWSPEC_ACTION_REDIRECT = BGPFlowSpecRedirectCommunity.ACTION_NAME
FLOWSPEC_ACTION_TRAFFIC_MARKING = BGPFlowSpecTrafficMarkingCommunity.ACTION_NAME
+FLOWSPEC_ACTION_VLAN = BGPFlowSpecVlanActionCommunity.ACTION_NAME
+FLOWSPEC_ACTION_TPID = BGPFlowSpecTPIDActionCommunity.ACTION_NAME
SUPPORTTED_FLOWSPEC_ACTIONS = (
FLOWSPEC_ACTION_TRAFFIC_RATE,
FLOWSPEC_ACTION_TRAFFIC_ACTION,
FLOWSPEC_ACTION_REDIRECT,
FLOWSPEC_ACTION_TRAFFIC_MARKING,
+ FLOWSPEC_ACTION_VLAN,
+ FLOWSPEC_ACTION_TPID,
)
diff --git a/ryu/services/protocols/bgp/base.py b/ryu/services/protocols/bgp/base.py
index 0dc86079..6295ed9e 100644
--- a/ryu/services/protocols/bgp/base.py
+++ b/ryu/services/protocols/bgp/base.py
@@ -40,6 +40,7 @@ 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_L2VPN_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
@@ -64,6 +65,7 @@ SUPPORTED_GLOBAL_RF = {
RF_IPv6_FLOWSPEC,
RF_VPNv4_FLOWSPEC,
RF_VPNv6_FLOWSPEC,
+ RF_L2VPN_FLOWSPEC,
}
diff --git a/ryu/services/protocols/bgp/bgp_sample_conf.py b/ryu/services/protocols/bgp/bgp_sample_conf.py
index 3f34fbdc..f18f0f75 100644
--- a/ryu/services/protocols/bgp/bgp_sample_conf.py
+++ b/ryu/services/protocols/bgp/bgp_sample_conf.py
@@ -5,6 +5,7 @@ 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 RF_L2VPN_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
@@ -18,8 +19,16 @@ 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_FAMILY_L2VPN
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 FLOWSPEC_VLAN_POP
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_PUSH
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_SWAP
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_RW_INNER
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_RW_OUTER
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_TPID_TI
+from ryu.services.protocols.bgp.bgpspeaker import FLOWSPEC_TPID_TO
from ryu.services.protocols.bgp.bgpspeaker import REDUNDANCY_MODE_SINGLE_ACTIVE
# =============================================================================
@@ -60,6 +69,7 @@ BGP = {
'enable_ipv6fs': True,
'enable_vpnv4fs': True,
'enable_vpnv6fs': True,
+ 'enable_l2vpnfs': True,
},
],
@@ -102,6 +112,13 @@ BGP = {
'export_rts': ['65001:300'],
'route_family': RF_VPNV6_FLOWSPEC,
},
+ # Example of VRF for L2VPN FlowSpec
+ {
+ 'route_dist': '65001:350',
+ 'import_rts': ['65001:350'],
+ 'export_rts': ['65001:350'],
+ 'route_family': RF_L2VPN_FLOWSPEC,
+ },
],
# List of BGP routes.
@@ -319,6 +336,53 @@ BGP = {
}
},
},
+ # Example of Flow Specification L2VPN prefix
+ {
+ 'flowspec_family': FLOWSPEC_FAMILY_L2VPN,
+ 'route_dist': '65001:350',
+ 'rules': {
+ 'ether_type': 0x0800,
+ 'src_mac': '12:34:56:78:90:AB',
+ 'dst_mac': 'BE:EF:C0:FF:EE:DD',
+ 'llc_dsap': 0x42,
+ 'llc_ssap': 0x42,
+ 'llc_control': 100,
+ 'snap': 0x12345,
+ 'vlan_id': '>4000',
+ 'vlan_cos': '>=3',
+ 'inner_vlan_id': '<3000',
+ 'inner_vlan_cos': '<=5',
+ },
+ '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,
+ },
+ 'vlan_action': {
+ 'actions_1': FLOWSPEC_VLAN_POP | FLOWSPEC_VLAN_PUSH,
+ 'vlan_1': 3000,
+ 'cos_1': 3,
+ 'actions_2': FLOWSPEC_VLAN_SWAP,
+ 'vlan_2': 4000,
+ 'cos_2': 2,
+ },
+ 'tpid_action': {
+ 'actions': FLOWSPEC_TPID_TI | FLOWSPEC_TPID_TO,
+ 'tpid_1': 200,
+ 'tpid_2': 300,
+ }
+ },
+ }
],
}
diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py
index 3c8d6450..c93eacba 100644
--- a/ryu/services/protocols/bgp/bgpspeaker.py
+++ b/ryu/services/protocols/bgp/bgpspeaker.py
@@ -18,7 +18,11 @@
import netaddr
from ryu.lib import hub
-from ryu.lib.packet.bgp import BGPFlowSpecTrafficActionCommunity
+from ryu.lib.packet.bgp import (
+ BGPFlowSpecTrafficActionCommunity,
+ BGPFlowSpecVlanActionCommunity,
+ BGPFlowSpecTPIDActionCommunity,
+)
from ryu.services.protocols.bgp.core_manager import CORE_MANAGER
from ryu.services.protocols.bgp.signals.emit import BgpSignalBus
@@ -60,6 +64,7 @@ from ryu.services.protocols.bgp.api.prefix import (
FLOWSPEC_FAMILY_VPNV4,
FLOWSPEC_FAMILY_IPV6,
FLOWSPEC_FAMILY_VPNV6,
+ FLOWSPEC_FAMILY_L2VPN,
FLOWSPEC_RULES,
FLOWSPEC_ACTIONS)
from ryu.services.protocols.bgp.rtconf.common import LOCAL_AS
@@ -87,6 +92,7 @@ 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_MBGP_L2VPNFS
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
@@ -101,6 +107,7 @@ from ryu.services.protocols.bgp.rtconf.neighbors import (
DEFAULT_CAP_MBGP_IPV6FS,
DEFAULT_CAP_MBGP_VPNV4FS,
DEFAULT_CAP_MBGP_VPNV6FS,
+ DEFAULT_CAP_MBGP_L2VPNFS,
)
from ryu.services.protocols.bgp.rtconf.neighbors import (
DEFAULT_CAP_ENHANCED_REFRESH, DEFAULT_CAP_FOUR_OCTET_AS_NUMBER)
@@ -131,11 +138,23 @@ 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
+RF_L2VPN_FLOWSPEC = vrfs.VRF_RF_L2VPN_FLOWSPEC
# Constants for the Traffic Filtering Actions of Flow Specification.
FLOWSPEC_TA_SAMPLE = BGPFlowSpecTrafficActionCommunity.SAMPLE
FLOWSPEC_TA_TERMINAL = BGPFlowSpecTrafficActionCommunity.TERMINAL
+# Constants for the VLAN Actions of Flow Specification.
+FLOWSPEC_VLAN_POP = BGPFlowSpecVlanActionCommunity.POP
+FLOWSPEC_VLAN_PUSH = BGPFlowSpecVlanActionCommunity.PUSH
+FLOWSPEC_VLAN_SWAP = BGPFlowSpecVlanActionCommunity.SWAP
+FLOWSPEC_VLAN_RW_INNER = BGPFlowSpecVlanActionCommunity.REWRITE_INNER
+FLOWSPEC_VLAN_RW_OUTER = BGPFlowSpecVlanActionCommunity.REWRITE_OUTER
+
+# Constants for the TPID Actions of Flow Specification.
+FLOWSPEC_TPID_TI = BGPFlowSpecTPIDActionCommunity.TI
+FLOWSPEC_TPID_TO = BGPFlowSpecTPIDActionCommunity.TO
+
class EventPrefix(object):
"""
@@ -366,6 +385,7 @@ class BGPSpeaker(object):
enable_ipv6fs=DEFAULT_CAP_MBGP_IPV6FS,
enable_vpnv4fs=DEFAULT_CAP_MBGP_VPNV4FS,
enable_vpnv6fs=DEFAULT_CAP_MBGP_VPNV6FS,
+ enable_l2vpnfs=DEFAULT_CAP_MBGP_L2VPNFS,
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,
@@ -414,6 +434,9 @@ class BGPSpeaker(object):
``enable_vpnv6fs`` enables VPNv6 Flow Specification address family
for this neighbor.
+ ``enable_l2vpnfs`` enables L2VPN Flow Specification address family
+ for this neighbor.
+
``enable_enhanced_refresh`` enables Enhanced Route Refresh for this
neighbor.
@@ -477,6 +500,7 @@ class BGPSpeaker(object):
CAP_MBGP_IPV6FS: enable_ipv6fs,
CAP_MBGP_VPNV4FS: enable_vpnv4fs,
CAP_MBGP_VPNV6FS: enable_vpnv6fs,
+ CAP_MBGP_L2VPNFS: enable_l2vpnfs,
}
if multi_exit_disc:
@@ -843,6 +867,7 @@ class BGPSpeaker(object):
- FLOWSPEC_FAMILY_IPV6 = 'ipv6fs'
- FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
- FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
+ - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs'
``rules`` specifies NLRIs of Flow Specification as
a dictionary type value.
@@ -853,6 +878,7 @@ class BGPSpeaker(object):
- :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv6NLRI`
- :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv4NLRI`
- :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv6NLRI`
+ - :py:mod:`ryu.lib.packet.bgp.FlowSpecL2VPNNLRI`
``route_dist`` specifies a route distinguisher value.
This parameter is required only if flowspec_family is one of the
@@ -860,6 +886,7 @@ class BGPSpeaker(object):
- FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
- FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
+ - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs'
``actions`` specifies Traffic Filtering Actions of
Flow Specification as a dictionary type value.
@@ -875,6 +902,8 @@ class BGPSpeaker(object):
traffic_action :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficActionCommunity`
redirect :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecRedirectCommunity`
traffic_marking :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficMarkingCommunity`
+ vlan_action :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecVlanActionCommunity`
+ tpid_action :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTPIDActionCommunity`
=============== ===============================================================
Example(IPv4)::
@@ -927,7 +956,8 @@ class BGPSpeaker(object):
FLOWSPEC_ACTIONS: actions or {},
}
- if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6]:
+ if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6,
+ FLOWSPEC_FAMILY_L2VPN]:
func_name = 'flowspec.add_local'
kwargs.update({ROUTE_DISTINGUISHER: route_dist})
@@ -951,7 +981,8 @@ class BGPSpeaker(object):
FLOWSPEC_RULES: rules,
}
- if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6]:
+ if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6,
+ FLOWSPEC_FAMILY_L2VPN]:
func_name = 'flowspec.del_local'
kwargs.update({ROUTE_DISTINGUISHER: route_dist})
@@ -978,6 +1009,7 @@ class BGPSpeaker(object):
- RF_L2_EVPN = 'evpn'
- RF_VPNV4_FLOWSPEC = 'ipv4fs'
- RF_VPNV6_FLOWSPEC = 'ipv6fs'
+ - RF_L2VPN_FLOWSPEC = 'l2vpnfs'
``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 27e0bd31..40fe943f 100644
--- a/ryu/services/protocols/bgp/core_managers/table_manager.py
+++ b/ryu/services/protocols/bgp/core_managers/table_manager.py
@@ -23,14 +23,19 @@ 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.info_base.l2vpnfs import L2VPNFlowSpecTable
+from ryu.services.protocols.bgp.info_base.vrfl2vpnfs import L2vpnFlowSpecPath
+from ryu.services.protocols.bgp.info_base.vrfl2vpnfs import L2vpnFlowSpecTable
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 VRF_RF_L2VPN_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.services.protocols.bgp.utils.bgp import create_l2vpnflowspec_actions
from ryu.lib import type_desc
from ryu.lib.packet.bgp import RF_IPv4_UC
@@ -42,6 +47,7 @@ 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_L2VPN_FLOWSPEC
from ryu.lib.packet.bgp import RF_RTC_UC
from ryu.lib.packet.bgp import BGPPathAttributeOrigin
from ryu.lib.packet.bgp import BGPPathAttributeAsPath
@@ -59,6 +65,7 @@ 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.lib.packet.bgp import FlowSpecL2VPNNLRI
from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4
from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4_prefix
@@ -143,6 +150,8 @@ class TableCoreManager(object):
vpn_table = self.get_vpnv4fs_table()
elif vrf_table.route_family == Vrf6FlowSpecTable.ROUTE_FAMILY:
vpn_table = self.get_vpnv6fs_table()
+ elif vrf_table.route_family == L2vpnFlowSpecTable.ROUTE_FAMILY:
+ vpn_table = self.get_l2vpnfs_table()
else:
raise ValueError('Invalid VRF table route family: %s' %
vrf_table.route_family)
@@ -217,6 +226,8 @@ class TableCoreManager(object):
global_table = self.get_vpnv4fs_table()
elif route_family == RF_VPNv6_FLOWSPEC:
global_table = self.get_vpnv6fs_table()
+ elif route_family == RF_L2VPN_FLOWSPEC:
+ global_table = self.get_l2vpnfs_table()
elif route_family == RF_RTC_UC:
global_table = self.get_rtc_table()
@@ -387,6 +398,21 @@ class TableCoreManager(object):
return vpnv6fs_table
+ def get_l2vpnfs_table(self):
+ """Returns global L2VPN Flow Specification table.
+
+ Creates the table if it does not exist.
+ """
+ l2vpnfs_table = self._global_tables.get(RF_L2VPN_FLOWSPEC)
+ # Lazy initialization of the table.
+ if not l2vpnfs_table:
+ l2vpnfs_table = L2VPNFlowSpecTable(self._core_service,
+ self._signal_bus)
+ self._global_tables[RF_L2VPN_FLOWSPEC] = l2vpnfs_table
+ self._tables[(None, RF_L2VPN_FLOWSPEC)] = l2vpnfs_table
+
+ return l2vpnfs_table
+
def get_nexthop_label(self, label_key):
return self._next_hop_label.get(label_key, None)
@@ -470,6 +496,8 @@ class TableCoreManager(object):
vrf_table = Vrf4FlowSpecTable
elif route_family == VRF_RF_IPV6_FLOWSPEC:
vrf_table = Vrf6FlowSpecTable
+ elif route_family == VRF_RF_L2VPN_FLOWSPEC:
+ vrf_table = L2vpnFlowSpecTable
else:
raise ValueError('Unsupported route family for VRF: %s' %
route_family)
@@ -557,6 +585,8 @@ class TableCoreManager(object):
route_family = RF_IPv4_FLOWSPEC
elif vpn_path.route_family == RF_VPNv6_FLOWSPEC:
route_family = RF_IPv6_FLOWSPEC
+ elif vpn_path.route_family == RF_L2VPN_FLOWSPEC:
+ route_family = RF_L2VPN_FLOWSPEC
else:
raise ValueError('Unsupported route family for VRF: %s' %
vpn_path.route_family)
@@ -702,6 +732,7 @@ class TableCoreManager(object):
from ryu.services.protocols.bgp.api.prefix import (
FLOWSPEC_FAMILY_VPNV4,
FLOWSPEC_FAMILY_VPNV6,
+ FLOWSPEC_FAMILY_L2VPN,
)
if flowspec_family == FLOWSPEC_FAMILY_VPNV4:
@@ -718,6 +749,13 @@ class TableCoreManager(object):
communities = create_v6flowspec_actions(actions)
except ValueError as e:
raise BgpCoreError(desc=str(e))
+ elif flowspec_family == FLOWSPEC_FAMILY_L2VPN:
+ vrf_table = self._tables.get((route_dist, VRF_RF_L2VPN_FLOWSPEC))
+ prefix = FlowSpecL2VPNNLRI.from_user(route_dist, **rules)
+ try:
+ communities = create_l2vpnflowspec_actions(actions)
+ except ValueError as e:
+ raise BgpCoreError(desc=str(e))
else:
raise BgpCoreError(
desc='Unsupported flowspec_family %s' % flowspec_family)
@@ -794,6 +832,7 @@ class TableCoreManager(object):
from ryu.services.protocols.bgp.api.prefix import (
FLOWSPEC_FAMILY_IPV4,
FLOWSPEC_FAMILY_IPV6,
+ FLOWSPEC_FAMILY_L2VPN,
)
src_ver_num = 1
@@ -833,6 +872,19 @@ class TableCoreManager(object):
pathattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = (
BGPPathAttributeExtendedCommunities(
communities=communities))
+ elif flowspec_family == FLOWSPEC_FAMILY_L2VPN:
+ _nlri = FlowSpecL2VPNNLRI.from_user(**rules)
+ p = L2vpnFlowSpecPath
+
+ try:
+ communities = create_l2vpnflowspec_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/info_base/vrf.py b/ryu/services/protocols/bgp/info_base/vrf.py
index 79940735..8b06c6a1 100644
--- a/ryu/services/protocols/bgp/info_base/vrf.py
+++ b/ryu/services/protocols/bgp/info_base/vrf.py
@@ -39,7 +39,10 @@ from ryu.lib.packet.bgp import PmsiTunnelIdIngressReplication
from ryu.lib.packet.bgp import RF_L2_EVPN
from ryu.lib.packet.bgp import EvpnMacIPAdvertisementNLRI
from ryu.lib.packet.bgp import EvpnIpPrefixNLRI
-from ryu.lib.packet.safi import IP_FLOWSPEC
+from ryu.lib.packet.safi import (
+ IP_FLOWSPEC,
+ VPN_FLOWSPEC,
+)
from ryu.services.protocols.bgp.base import OrderedDict
from ryu.services.protocols.bgp.constants import VPN_TABLE
@@ -168,7 +171,7 @@ class VrfTable(Table):
# Because NLRI class is the same if the route family is EVPN,
# we re-use the NLRI instance.
vrf_nlri = vpn_path.nlri
- elif self.ROUTE_FAMILY.safi == IP_FLOWSPEC:
+ elif self.ROUTE_FAMILY.safi in [IP_FLOWSPEC, VPN_FLOWSPEC]:
vrf_nlri = self.NLRI_CLASS(rules=vpn_path.nlri.rules)
else: # self.VPN_ROUTE_FAMILY in [RF_IPv4_VPN, RF_IPv6_VPN]
# Copy NLRI instance
@@ -526,7 +529,7 @@ class VrfPath(Path):
- `label_list`: (list) List of labels for this path.
Note: other parameters are as documented in super class.
"""
- if self.ROUTE_FAMILY.safi == IP_FLOWSPEC:
+ if self.ROUTE_FAMILY.safi in [IP_FLOWSPEC, VPN_FLOWSPEC]:
nexthop = '0.0.0.0'
Path.__init__(self, source, nlri, src_ver_num, pattrs, nexthop,
@@ -584,7 +587,7 @@ class VrfPath(Path):
# we re-use the NLRI instance.
vpn_nlri = self._nlri
- elif self.ROUTE_FAMILY.safi == IP_FLOWSPEC:
+ elif self.ROUTE_FAMILY.safi in [IP_FLOWSPEC, VPN_FLOWSPEC]:
vpn_nlri = self.VPN_NLRI_CLASS(route_dist=route_dist,
rules=self.nlri.rules)
diff --git a/ryu/services/protocols/bgp/model.py b/ryu/services/protocols/bgp/model.py
index faa33f04..db325580 100644
--- a/ryu/services/protocols/bgp/model.py
+++ b/ryu/services/protocols/bgp/model.py
@@ -101,11 +101,15 @@ class FlexinetOutgoingRoute(object):
Vrf4FlowSpecPath)
from ryu.services.protocols.bgp.info_base.vrf6fs import (
Vrf6FlowSpecPath)
+ from ryu.services.protocols.bgp.info_base.vrfl2vpnfs import (
+ L2vpnFlowSpecPath)
assert path.route_family in (Vrf4Path.ROUTE_FAMILY,
Vrf6Path.ROUTE_FAMILY,
VrfEvpnPath.ROUTE_FAMILY,
Vrf4FlowSpecPath.ROUTE_FAMILY,
- Vrf6FlowSpecPath.ROUTE_FAMILY)
+ Vrf6FlowSpecPath.ROUTE_FAMILY,
+ L2vpnFlowSpecPath.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 d839d385..c445a87a 100644
--- a/ryu/services/protocols/bgp/rtconf/base.py
+++ b/ryu/services/protocols/bgp/rtconf/base.py
@@ -50,6 +50,7 @@ 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_MBGP_L2VPNFS = 'cap_mbgp_l2vpnfs'
CAP_RTC = 'cap_rtc'
RTC_AS = 'rtc_as'
HOLD_TIME = 'hold_time'
@@ -688,6 +689,15 @@ def validate_cap_mbgp_vpnv66fs(cmv6fs):
return cmv6fs
+@validate(name=CAP_MBGP_L2VPNFS)
+def validate_cap_mbgp_l2vpnfs(cml2fs):
+ if not isinstance(cml2fs, bool):
+ raise ConfigTypeError(desc='Invalid MP-BGP '
+ 'L2VPN Flow Specification capability '
+ 'settings: %s. Boolean value expected' % cml2fs)
+ return cml2fs
+
+
@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 d99e509a..e4490c19 100644
--- a/ryu/services/protocols/bgp/rtconf/neighbors.py
+++ b/ryu/services/protocols/bgp/rtconf/neighbors.py
@@ -31,6 +31,7 @@ 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_L2VPN_FLOWSPEC
from ryu.lib.packet.bgp import RF_RTC_UC
from ryu.lib.packet.bgp import BGPOptParamCapabilityFourOctetAsNumber
from ryu.lib.packet.bgp import BGPOptParamCapabilityEnhancedRouteRefresh
@@ -56,6 +57,7 @@ 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_MBGP_L2VPNFS
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
@@ -117,6 +119,7 @@ DEFAULT_CAP_MBGP_IPV4FS = False
DEFAULT_CAP_MBGP_IPV6FS = False
DEFAULT_CAP_MBGP_VPNV4FS = False
DEFAULT_CAP_MBGP_VPNV6FS = False
+DEFAULT_CAP_MBGP_L2VPNFS = False
DEFAULT_HOLD_TIME = 40
DEFAULT_ENABLED = True
DEFAULT_CAP_RTC = False
@@ -332,6 +335,7 @@ class NeighborConf(ConfWithId, ConfWithStats):
CAP_RTC, CAP_MBGP_EVPN,
CAP_MBGP_IPV4FS, CAP_MBGP_VPNV4FS,
CAP_MBGP_IPV6FS, CAP_MBGP_VPNV6FS,
+ CAP_MBGP_L2VPNFS,
RTC_AS, HOLD_TIME,
ENABLED, MULTI_EXIT_DISC, MAX_PREFIXES,
ADVERTISE_PEER_AS, SITE_OF_ORIGINS,
@@ -372,6 +376,8 @@ class NeighborConf(ConfWithId, ConfWithStats):
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[CAP_MBGP_L2VPNFS] = compute_optional_conf(
+ CAP_MBGP_L2VPNFS, DEFAULT_CAP_MBGP_L2VPNFS, **kwargs)
self._settings[HOLD_TIME] = compute_optional_conf(
HOLD_TIME, DEFAULT_HOLD_TIME, **kwargs)
self._settings[ENABLED] = compute_optional_conf(
@@ -558,6 +564,10 @@ class NeighborConf(ConfWithId, ConfWithStats):
return self._settings[CAP_MBGP_VPNV6FS]
@property
+ def cap_mbgp_l2vpnfs(self):
+ return self._settings[CAP_MBGP_L2VPNFS]
+
+ @property
def cap_rtc(self):
return self._settings[CAP_RTC]
@@ -701,6 +711,11 @@ class NeighborConf(ConfWithId, ConfWithStats):
BGPOptParamCapabilityMultiprotocol(
RF_VPNv6_FLOWSPEC.afi, RF_VPNv6_FLOWSPEC.safi))
+ if self.cap_mbgp_l2vpnfs:
+ mbgp_caps.append(
+ BGPOptParamCapabilityMultiprotocol(
+ RF_L2VPN_FLOWSPEC.afi, RF_L2VPN_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 a918c5b9..72958df2 100644
--- a/ryu/services/protocols/bgp/rtconf/vrfs.py
+++ b/ryu/services/protocols/bgp/rtconf/vrfs.py
@@ -25,6 +25,7 @@ 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.lib.packet.bgp import RF_L2VPN_FLOWSPEC
from ryu.services.protocols.bgp.utils import validation
from ryu.services.protocols.bgp.base import get_validator
@@ -63,12 +64,14 @@ VRF_RF_IPV6 = 'ipv6'
VRF_RF_L2_EVPN = 'evpn'
VRF_RF_IPV4_FLOWSPEC = 'ipv4fs'
VRF_RF_IPV6_FLOWSPEC = 'ipv6fs'
+VRF_RF_L2VPN_FLOWSPEC = 'l2vpnfs'
SUPPORTED_VRF_RF = (
VRF_RF_IPV4,
VRF_RF_IPV6,
VRF_RF_L2_EVPN,
VRF_RF_IPV4_FLOWSPEC,
VRF_RF_IPV6_FLOWSPEC,
+ VRF_RF_L2VPN_FLOWSPEC,
)
@@ -240,6 +243,8 @@ class VrfConf(ConfWithId, ConfWithStats):
return RF_IPv4_FLOWSPEC
elif vrf_rf == VRF_RF_IPV6_FLOWSPEC:
return RF_IPv6_FLOWSPEC
+ elif vrf_rf == VRF_RF_L2VPN_FLOWSPEC:
+ return RF_L2VPN_FLOWSPEC
else:
raise ValueError('Unsupported VRF route family given %s' % vrf_rf)
@@ -255,6 +260,8 @@ class VrfConf(ConfWithId, ConfWithStats):
return VRF_RF_IPV4_FLOWSPEC
elif route_family == RF_IPv6_FLOWSPEC:
return VRF_RF_IPV6_FLOWSPEC
+ elif route_family == RF_L2VPN_FLOWSPEC:
+ return VRF_RF_L2VPN_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 2d066944..5a9824d1 100644
--- a/ryu/services/protocols/bgp/utils/bgp.py
+++ b/ryu/services/protocols/bgp/utils/bgp.py
@@ -32,6 +32,7 @@ from ryu.lib.packet.bgp import (
RF_IPv6_FLOWSPEC,
RF_VPNv4_FLOWSPEC,
RF_VPNv6_FLOWSPEC,
+ RF_L2VPN_FLOWSPEC,
RF_RTC_UC,
RouteTargetMembershipNLRI,
BGP_ATTR_TYPE_MULTI_EXIT_DISC,
@@ -49,6 +50,8 @@ from ryu.lib.packet.bgp import (
BGPFlowSpecTrafficActionCommunity,
BGPFlowSpecRedirectCommunity,
BGPFlowSpecTrafficMarkingCommunity,
+ BGPFlowSpecVlanActionCommunity,
+ BGPFlowSpecTPIDActionCommunity,
)
from ryu.services.protocols.bgp.info_base.rtc import RtcPath
from ryu.services.protocols.bgp.info_base.ipv4 import Ipv4Path
@@ -60,6 +63,7 @@ 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
+from ryu.services.protocols.bgp.info_base.l2vpnfs import L2VPNFlowSpecPath
LOG = logging.getLogger('utils.bgp')
@@ -74,6 +78,7 @@ _ROUTE_FAMILY_TO_PATH_MAP = {RF_IPv4_UC: Ipv4Path,
RF_IPv6_FLOWSPEC: IPv6FlowSpecPath,
RF_VPNv4_FLOWSPEC: VPNv4FlowSpecPath,
RF_VPNv6_FLOWSPEC: VPNv6FlowSpecPath,
+ RF_L2VPN_FLOWSPEC: L2VPNFlowSpecPath,
RF_RTC_UC: RtcPath}
@@ -249,6 +254,32 @@ def create_v6flowspec_actions(actions=None):
return _create_actions(actions, action_types)
+def create_l2vpnflowspec_actions(actions=None):
+ """
+ Create list of traffic filtering actions for L2VPN Flow Specification.
+ """
+ from ryu.services.protocols.bgp.api.prefix import (
+ FLOWSPEC_ACTION_TRAFFIC_RATE,
+ FLOWSPEC_ACTION_TRAFFIC_ACTION,
+ FLOWSPEC_ACTION_REDIRECT,
+ FLOWSPEC_ACTION_TRAFFIC_MARKING,
+ FLOWSPEC_ACTION_VLAN,
+ FLOWSPEC_ACTION_TPID,
+ )
+
+ # Supported action type for L2VPN.
+ action_types = {
+ FLOWSPEC_ACTION_TRAFFIC_RATE: BGPFlowSpecTrafficRateCommunity,
+ FLOWSPEC_ACTION_TRAFFIC_ACTION: BGPFlowSpecTrafficActionCommunity,
+ FLOWSPEC_ACTION_REDIRECT: BGPFlowSpecRedirectCommunity,
+ FLOWSPEC_ACTION_TRAFFIC_MARKING: BGPFlowSpecTrafficMarkingCommunity,
+ FLOWSPEC_ACTION_VLAN: BGPFlowSpecVlanActionCommunity,
+ FLOWSPEC_ACTION_TPID: BGPFlowSpecTPIDActionCommunity,
+ }
+
+ return _create_actions(actions, action_types)
+
+
def _create_actions(actions, action_types):
communities = []