summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ryu/lib/packet/bgp.py20
-rw-r--r--ryu/services/protocols/bgp/api/base.py1
-rw-r--r--ryu/services/protocols/bgp/api/prefix.py24
-rw-r--r--ryu/services/protocols/bgp/bgpspeaker.py11
-rw-r--r--ryu/services/protocols/bgp/core_managers/table_manager.py4
-rw-r--r--ryu/services/protocols/bgp/info_base/vrf.py11
6 files changed, 65 insertions, 6 deletions
diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py
index 6b39f2dc..6d7cf3f6 100644
--- a/ryu/lib/packet/bgp.py
+++ b/ryu/lib/packet/bgp.py
@@ -2795,6 +2795,26 @@ class BGPEncapsulationExtendedCommunity(_ExtendedCommunity):
super(BGPEncapsulationExtendedCommunity, self).__init__()
self.do_init(BGPEncapsulationExtendedCommunity, self, kwargs)
+ @classmethod
+ def from_str(cls, tunnel_type):
+ """
+ Returns an instance identified with the given `tunnel_type`.
+
+ `tunnel_type` should be a str type value and corresponding to
+ BGP Tunnel Encapsulation Attribute Tunnel Type constants name
+ omitting `TUNNEL_TYPE_` prefix.
+
+ Example:
+ - `gre` means TUNNEL_TYPE_GRE
+ - `vxlan` means TUNNEL_TYPE_VXLAN
+
+ And raises AttributeError when the corresponding Tunnel Type
+ is not found to the given `tunnel_type`.
+ """
+ return cls(subtype=_ExtendedCommunity.SUBTYPE_ENCAPSULATION,
+ tunnel_type=getattr(cls,
+ 'TUNNEL_TYPE_' + tunnel_type.upper()))
+
@_ExtendedCommunity.register_type(_ExtendedCommunity.EVPN_MAC_MOBILITY)
class BGPEvpnMacMobilityExtendedCommunity(_ExtendedCommunity):
diff --git a/ryu/services/protocols/bgp/api/base.py b/ryu/services/protocols/bgp/api/base.py
index 9624e7be..49e78063 100644
--- a/ryu/services/protocols/bgp/api/base.py
+++ b/ryu/services/protocols/bgp/api/base.py
@@ -49,6 +49,7 @@ EVPN_ETHERNET_TAG_ID = 'ethernet_tag_id'
MAC_ADDR = 'mac_addr'
IP_ADDR = 'ip_addr'
MPLS_LABELS = 'mpls_labels'
+TUNNEL_TYPE = 'tunnel_type'
# API call registry
_CALL_REGISTRY = {}
diff --git a/ryu/services/protocols/bgp/api/prefix.py b/ryu/services/protocols/bgp/api/prefix.py
index f047b6ae..2bcb4e08 100644
--- a/ryu/services/protocols/bgp/api/prefix.py
+++ b/ryu/services/protocols/bgp/api/prefix.py
@@ -31,6 +31,7 @@ from ryu.services.protocols.bgp.api.base import PREFIX
from ryu.services.protocols.bgp.api.base import RegisterWithArgChecks
from ryu.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER
from ryu.services.protocols.bgp.api.base import VPN_LABEL
+from ryu.services.protocols.bgp.api.base import TUNNEL_TYPE
from ryu.services.protocols.bgp.base import add_bgp_error_metadata
from ryu.services.protocols.bgp.base import PREFIX_ERROR_CODE
from ryu.services.protocols.bgp.base import validate
@@ -54,6 +55,20 @@ SUPPORTED_EVPN_ROUTE_TYPES = [
EVPN_MULTICAST_ETAG_ROUTE,
]
+# Constants for BGP Tunnel Encapsulation Attribute
+TUNNEL_TYPE_VXLAN = 'vxlan'
+TUNNEL_TYPE_NVGRE = 'nvgre'
+TUNNEL_TYPE_MPLS = 'mpls'
+TUNNEL_TYPE_MPLS_IN_GRE = 'mpls_in_gre'
+TUNNEL_TYPE_VXLAN_GRE = 'vxlan_gre'
+SUPPORTED_TUNNEL_TYPES = [
+ TUNNEL_TYPE_VXLAN,
+ TUNNEL_TYPE_NVGRE,
+ TUNNEL_TYPE_MPLS,
+ TUNNEL_TYPE_MPLS_IN_GRE,
+ TUNNEL_TYPE_VXLAN_GRE,
+]
+
@add_bgp_error_metadata(code=PREFIX_ERROR_CODE,
sub_code=1,
@@ -122,6 +137,13 @@ def is_valid_mpls_labels(labels):
conf_value=labels)
+@validate(name=TUNNEL_TYPE)
+def is_valid_tunnel_type(tunnel_type):
+ if tunnel_type not in SUPPORTED_TUNNEL_TYPES:
+ raise ConfigValueError(conf_name=TUNNEL_TYPE,
+ conf_value=tunnel_type)
+
+
@RegisterWithArgChecks(name='prefix.add_local',
req_args=[ROUTE_DISTINGUISHER, PREFIX, NEXT_HOP],
opt_args=[VRF_RF])
@@ -171,7 +193,7 @@ def delete_local(route_dist, prefix, route_family=VRF_RF_IPV4):
req_args=[EVPN_ROUTE_TYPE, ROUTE_DISTINGUISHER,
NEXT_HOP],
opt_args=[EVPN_ESI, EVPN_ETHERNET_TAG_ID, MAC_ADDR,
- IP_ADDR])
+ IP_ADDR, TUNNEL_TYPE])
def add_evpn_local(route_type, route_dist, next_hop, **kwargs):
"""Adds EVPN route from VRF identified by *route_dist*.
"""
diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py
index 582e38d0..879eaf24 100644
--- a/ryu/services/protocols/bgp/bgpspeaker.py
+++ b/ryu/services/protocols/bgp/bgpspeaker.py
@@ -31,8 +31,10 @@ from ryu.services.protocols.bgp.api.base import MAC_ADDR
from ryu.services.protocols.bgp.api.base import NEXT_HOP
from ryu.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER
from ryu.services.protocols.bgp.api.base import ROUTE_FAMILY
+from ryu.services.protocols.bgp.api.base import TUNNEL_TYPE
from ryu.services.protocols.bgp.api.prefix import EVPN_MAC_IP_ADV_ROUTE
from ryu.services.protocols.bgp.api.prefix import EVPN_MULTICAST_ETAG_ROUTE
+from ryu.services.protocols.bgp.api.prefix import TUNNEL_TYPE_MPLS
from ryu.services.protocols.bgp.rtconf.common import LOCAL_AS
from ryu.services.protocols.bgp.rtconf.common import ROUTER_ID
from ryu.services.protocols.bgp.rtconf.common import BGP_SERVER_PORT
@@ -490,7 +492,7 @@ class BGPSpeaker(object):
def evpn_prefix_add(self, route_type, route_dist, esi=0,
ethernet_tag_id=None, mac_addr=None, ip_addr=None,
- next_hop=None):
+ next_hop=None, tunnel_type=TUNNEL_TYPE_MPLS):
""" This method adds a new EVPN route to be advertised.
``route_type`` specifies one of the EVPN route type name. The
@@ -509,6 +511,9 @@ class BGPSpeaker(object):
``ip_addr`` specifies an IPv4 or IPv6 address to advertise.
``next_hop`` specifies the next hop address for this prefix.
+
+ ``tunnel_type`` specifies the data plane encapsulation type
+ to advertise. The default is the MPLS encapsulation type.
"""
func_name = 'evpn_prefix.add_local'
@@ -521,6 +526,10 @@ class BGPSpeaker(object):
ROUTE_DISTINGUISHER: route_dist,
NEXT_HOP: next_hop}
+ # Set optional arguments
+ if tunnel_type:
+ kwargs[TUNNEL_TYPE] = tunnel_type
+
# Set route type specific arguments
if route_type == EVPN_MAC_IP_ADV_ROUTE:
kwargs.update({
diff --git a/ryu/services/protocols/bgp/core_managers/table_manager.py b/ryu/services/protocols/bgp/core_managers/table_manager.py
index b8285ca4..5320dbfa 100644
--- a/ryu/services/protocols/bgp/core_managers/table_manager.py
+++ b/ryu/services/protocols/bgp/core_managers/table_manager.py
@@ -482,7 +482,7 @@ class TableCoreManager(object):
LOG.debug('No VRF table found that imports RTs: %s', path_rts)
def update_vrf_table(self, route_dist, prefix=None, next_hop=None,
- route_family=None, route_type=None,
+ route_family=None, route_type=None, tunnel_type=None,
is_withdraw=False, **kwargs):
"""Update a BGP route in the VRF table identified by `route_dist`
with the given `next_hop`.
@@ -547,7 +547,7 @@ class TableCoreManager(object):
# withdrawal. Hence multiple withdrawals have not side effect.
return vrf_table.insert_vrf_path(
nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl,
- is_withdraw=is_withdraw)
+ is_withdraw=is_withdraw, tunnel_type=tunnel_type)
def update_global_table(self, prefix, next_hop=None, is_withdraw=False):
"""Update a BGP route in the Global table for the given `prefix`
diff --git a/ryu/services/protocols/bgp/info_base/vrf.py b/ryu/services/protocols/bgp/info_base/vrf.py
index 620d5226..6a60fc82 100644
--- a/ryu/services/protocols/bgp/info_base/vrf.py
+++ b/ryu/services/protocols/bgp/info_base/vrf.py
@@ -30,6 +30,7 @@ from ryu.lib.packet.bgp import BGPPathAttributeAsPath
from ryu.lib.packet.bgp import BGPPathAttributeExtendedCommunities
from ryu.lib.packet.bgp import BGPTwoOctetAsSpecificExtendedCommunity
from ryu.lib.packet.bgp import BGPPathAttributeMultiExitDisc
+from ryu.lib.packet.bgp import BGPEncapsulationExtendedCommunity
from ryu.lib.packet.bgp import RF_L2_EVPN
from ryu.lib.packet.bgp import EvpnMacIPAdvertisementNLRI
@@ -211,7 +212,7 @@ class VrfTable(Table):
return changed_dests
def insert_vrf_path(self, nlri, next_hop=None,
- gen_lbl=False, is_withdraw=False):
+ gen_lbl=False, is_withdraw=False, **kwargs):
assert nlri
pattrs = None
label_list = []
@@ -243,6 +244,12 @@ class VrfTable(Table):
local_administrator=int(local_admin),
subtype=subtype))
+ # Set Tunnel Encapsulation Attribute
+ tunnel_type = kwargs.get('tunnel_type', None)
+ if tunnel_type:
+ communities.append(
+ BGPEncapsulationExtendedCommunity.from_str(tunnel_type))
+
pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = \
BGPPathAttributeExtendedCommunities(communities=communities)
if vrf_conf.multi_exit_disc:
@@ -266,7 +273,7 @@ class VrfTable(Table):
label_list.append(table_manager.get_next_vpnv4_label())
# Set MPLS labels with the generated labels
- if isinstance(nlri, EvpnMacIPAdvertisementNLRI):
+ if gen_lbl and isinstance(nlri, EvpnMacIPAdvertisementNLRI):
nlri.mpls_labels = label_list[:2]
puid = self.VRF_PATH_CLASS.create_puid(