Sriram | 22 Sep 04:35 2014
Picon

RYU Patches

Hi,

Attached are 2patches:

0001-Fix-spell-check-in-group-feature-message.patch:

The above patch fixes some spell check and improves consistency when calling DSCP_REMARK meter type

0001-Improve-debug-messages-for-unsupported-request.patch

This patch improves the debug messages for unsupported request. Previously, when a request is not supported in that OF protocol version, it logs as "Unsupported OF protocol" which is incorrect. The switch might still support that OF protocol. So this patch improves the debug message to log as "Request not supported in this OF protocol version"

Hope this helps.

Thanks,
Sriram
------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Davide Sanvito | 21 Sep 17:27 2014
Picon

Python Interactive console

How can I open a Python Interactive console from a RyuApp?
I'd like to run my app through ryu-manager but install flow rules on demand 
by calling functions inside my RyuApp.
Thanks

------------------------------------------------------------------------------
Slashdot TV.  Video for Nerds.  Stuff that Matters.
http://pubads.g.doubleclick.net/gampad/clk?id=160591471&iu=/4140/ostg.clktrk
游荡的风 | 20 Sep 11:27 2014

need ur help

Dear,

To implement flow-based tunnel, I need to generate a flow entry to set the tunnel destination like this:

 "cookie=0x0, duration=4.700s, table=0, n_packets=0, n_bytes=0, idle_age=4, actions=load:0x1010101->NXM_NX_TUN_IPV4_DST[],output:2"

It seems this action is not implemented in the current code of ryu.  my question,  how can it be added? if you can provide some sample code, it is really helpful. Thanks in advance!

Best Regards,


tom

 
------------------------------------------------------------------------------
Slashdot TV.  Video for Nerds.  Stuff that Matters.
http://pubads.g.doubleclick.net/gampad/clk?id=160591471&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Karthik Sharma | 20 Sep 09:53 2014
Picon

RYU API to pre-program the flows into the switches

I am using the below function inside my simple_switch.py to populate the flows to the switches.


 def populate_of_flow(self,datapath,msg,src,dst):
        ofproto = datapath.ofproto
        dpid = datapath.id
         self.mac_to_port.setdefault(dpid, {})

         # learn a mac address to avoid FLOOD next time.
         self.mac_to_port[dpid][src] = msg.in_port

         if dst in self.mac_to_port[dpid]:
             out_port = self.mac_to_port[dpid][dst]
         else:
             out_port = ofproto.OFPP_FLOOD
 
         actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
 
         fe_key = format_dpid_str(dpid_to_str(datapath.id)) + str(msg.in_port)
         fe_list = self.g.vertices.index.lookup(switch_dpid_port=fe_key)
         for fe in fe_list:
             #print('flow entries for switch {} has output port {} action {}'.format(fe.switch_dpid,fe.actionOutputPort,fe.actions))
             outport = fe.actionOutputPort
 
         actions = [datapath.ofproto_parser.OFPActionOutput(outport)]
 
         # install a flow to avoid packet_in next time
         if out_port != ofproto.OFPP_FLOOD:
             self.add_flow(datapath, msg.in_port, dst, actions)
 
         print('msg.buffer_id {}'.format(msg.buffer_id))
         out = datapath.ofproto_parser.OFPPacketOut(
             datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
             actions=actions)
        datapath.send_msg(out)

As you can see above,it requires the "msg.buffer_id.".Now this "msg" comes from the PACKET_IN event which is passed on to the event handler.I would like to know if there is a more generic API
that I can use to populate the flows given that I know the path and want to preprogram the flows.

Regards,
Karthik
------------------------------------------------------------------------------
Slashdot TV.  Video for Nerds.  Stuff that Matters.
http://pubads.g.doubleclick.net/gampad/clk?id=160591471&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Santiago Velez saffon | 19 Sep 17:45 2014
Picon

Using rest_qos to open queues.

Hello All.

I am trying to use the rest_qos.py file that provides QOS functionalities. But I am unsure how to create the
syntax of the messages. What I am trying is to open a new queue. here is my piece of code >

			##create rest requets for creating a queue
			rest_cmd={}
			rest_cmd[REST_QUEUE_TYPE]='linux-htb'			
			rest_cmd[REST_QUEUE_MAX_RATE]=10
			
			#Configure the queues that we will use
			queues=[]			
			
			queue={}
			queue[REST_QUEUE_MAX_RATE]=10
			queue[REST_QUEUE_MIN_RATE]=1						
			queues.append(queue)#Here we can add as many queues as we want
			
			#add the ques to our rest command			
			rest_cmd[REST_QUEUES]=queues
			
			
			#We need to call this function ::)
			#QoS.set_ovsdb_addr()			
			addres='tcp:0.0.0.0:8080'
			ofs.set_ovsdb_addr(dpid, addres)

The error I am receiving is:

ValueError: ValueError: ovsdb addr is not available.

127.0.0.1 - - [19/Sep/2014 08:35:03] code 400, message Bad request syntax ('{"id":0,"method":"get_schema","params":["Open_vSwitch"]}')
127.0.0.1 - - [19/Sep/2014 08:35:03] "{"id":0,"method":"get_schema","params":["Open_vSwitch"]}"
400 -

Can someone guide me in how the message syntax is created  :)

thanks for your help and time

------------------------------------------------------------------------------
Slashdot TV.  Video for Nerds.  Stuff that Matters.
http://pubads.g.doubleclick.net/gampad/clk?id=160591471&iu=/4140/ostg.clktrk
Cleber Araujo | 19 Sep 13:57 2014
Picon

Change link speed during emulation

Hello everybody! 

I'm doing some tests and I'm with some doubts: 

Is possible change the speed of a link during emulation? 

How to measure the workload of a switch? 

Thank you.


--
Cleber Araújo
Master student in Computer Science 
Federal University of Bahia
------------------------------------------------------------------------------
Slashdot TV.  Video for Nerds.  Stuff that Matters.
http://pubads.g.doubleclick.net/gampad/clk?id=160591471&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Hiroshi Yokoi | 19 Sep 10:24 2014
Picon

[PATCH] bgp: ignore link-local address

According to RFC 2545, both a global address and a link-local address
can be sent as a next_hop address in BGPUpdate message.
Since the link-local address is not needed in Ryu BGP,
Ryu BGP ignore it if the address family is IPv6 unicast.

Signed-off-by: Hiroshi Yokoi <yokoi.hiroshi@...>
---
 ryu/lib/packet/bgp.py | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py
index 60e3b49..ff6d7af 100644
--- a/ryu/lib/packet/bgp.py
+++ b/ryu/lib/packet/bgp.py
 <at>  <at>  -2014,6 +2014,16  <at>  <at>  class BGPPathAttributeMpReachNLRI(_PathAttribute):
         elif afi == addr_family.IP:
             next_hop = addrconv.ipv4.bin_to_text(next_hop_bin)
         elif afi == addr_family.IP6:
+            # next_hop_bin can include global address and link-local address
+            # according to RFC2545. Since a link-local address isn't needed in
+            # Ryu BGPSpeaker, we ignore it if both addresses were sent.
+            # The link-local address is supposed to follow after
+            # a global address and next_hop_len will be 32 bytes,
+            # so we use the first 16 bytes, which is a global address,
+            # as a next_hop and change the next_hop_len to 16.
+            if next_hop_len == 32:
+                next_hop_bin = next_hop_bin[:16]
+                next_hop_len = 16
             next_hop = addrconv.ipv6.bin_to_text(next_hop_bin)
         else:
             raise ValueError('Invalid address familly(%d)' % afi)
--

-- 
1.8.5.2 (Apple Git-48)

------------------------------------------------------------------------------
Slashdot TV.  Video for Nerds.  Stuff that Matters.
http://pubads.g.doubleclick.net/gampad/clk?id=160591471&iu=/4140/ostg.clktrk
Hiroshi Yokoi | 18 Sep 14:23 2014
Picon

[PATCH] bgp: local preference support IPv6, VPNv4/v6 route family

local preference supports IPv6 and VPNv4/v6 route family.
sorry, previous patch contains pep8 warnings, so I cleaned them.
Please discard previous one.

Signed-off-by: Hiroshi Yokoi <yokoi.hiroshi@...>
---
 ryu/services/protocols/bgp/api/rtconf.py           | 45 +++++++++++++---
 ryu/services/protocols/bgp/bgpspeaker.py           | 29 ++++++++++-
 ryu/services/protocols/bgp/constants.py            |  6 +++
 .../bgp/core_managers/configuration_manager.py     |  8 +++
 ryu/services/protocols/bgp/info_base/base.py       |  8 +--
 ryu/services/protocols/bgp/peer.py                 | 60 ++++++++++++++--------
 6 files changed, 122 insertions(+), 34 deletions(-)

diff --git a/ryu/services/protocols/bgp/api/rtconf.py b/ryu/services/protocols/bgp/api/rtconf.py
index ce98903..079a2f5 100644
--- a/ryu/services/protocols/bgp/api/rtconf.py
+++ b/ryu/services/protocols/bgp/api/rtconf.py
 <at>  <at>  -29,6 +29,7  <at>  <at>  from ryu.services.protocols.bgp.rtconf.vrfs import ROUTE_DISTINGUISHER
 from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF
 from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4
 from ryu.services.protocols.bgp.rtconf.vrfs import VrfConf
+from ryu.services.protocols.bgp import constants as const

 LOG = logging.getLogger('bgpspeaker.api.rtconf')

 <at>  <at>  -152,22 +153,50  <at>  <at>  def set_neighbor_in_filter(neigh_ip_address, filters):

  <at> RegisterWithArgChecks(name='neighbor.attribute_map.set',
                        req_args=[neighbors.IP_ADDRESS,
-                                 neighbors.ATTRIBUTE_MAP])
-def set_neighbor_attribute_map(neigh_ip_address, attribute_maps):
-    """Returns a neighbor attribute_map for given ip address if exists."""
+                                 neighbors.ATTRIBUTE_MAP],
+                       opt_args=[ROUTE_DISTINGUISHER, VRF_RF])
+def set_neighbor_attribute_map(neigh_ip_address, at_maps,
+                               route_dist=None, route_family=VRF_RF_IPV4):
+    """set attribute_maps to the neighbor."""
     core = CORE_MANAGER.get_core_service()
     peer = core.peer_manager.get_by_addr(neigh_ip_address)
-    peer.attribute_maps = attribute_maps
+
+    at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT
+    at_maps_dict = {}
+
+    if route_dist is not None:
+        vrf_conf =\
+            CORE_MANAGER.vrfs_conf.get_vrf_conf(route_dist, route_family)
+        if vrf_conf:
+            at_maps_key = ':'.join([route_dist, route_family])
+        else:
+            raise RuntimeConfigError(desc='No VrfConf with rd %s' %
+                                          route_dist)
+
+    at_maps_dict[const.ATTR_MAPS_LABEL_KEY] = at_maps_key
+    at_maps_dict[const.ATTR_MAPS_VALUE] = at_maps
+    peer.attribute_maps = at_maps_dict
+
     return True

 
  <at> RegisterWithArgChecks(name='neighbor.attribute_map.get',
-                       req_args=[neighbors.IP_ADDRESS])
-def get_neighbor_attribute_map(neigh_ip_address):
+                       req_args=[neighbors.IP_ADDRESS],
+                       opt_args=[ROUTE_DISTINGUISHER, VRF_RF])
+def get_neighbor_attribute_map(neigh_ip_address, route_dist=None,
+                               route_family=VRF_RF_IPV4):
     """Returns a neighbor attribute_map for given ip address if exists."""
     core = CORE_MANAGER.get_core_service()
-    ret = core.peer_manager.get_by_addr(neigh_ip_address).attribute_maps
-    return ret
+    peer = core.peer_manager.get_by_addr(neigh_ip_address)
+    at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT
+
+    if route_dist is not None:
+        at_maps_key = ':'.join([route_dist, route_family])
+    at_maps = peer.attribute_maps.get(at_maps_key)
+    if at_maps:
+        return at_maps.get(const.ATTR_MAPS_ORG_KEY)
+    else:
+        return []

 # =============================================================================
 # VRF configuration related APIs
diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py
index 9844e08..59e781c 100644
--- a/ryu/services/protocols/bgp/bgpspeaker.py
+++ b/ryu/services/protocols/bgp/bgpspeaker.py
 <at>  <at>  -526,7 +526,8  <at>  <at>  class BGPSpeaker(object):
         param['port'] = port
         call(func_name, **param)

-    def attribute_map_set(self, address, attribute_maps):
+    def attribute_map_set(self, address, attribute_maps,
+                          route_dist=None, route_family=RF_VPN_V4):
         """This method sets attribute mapping to a neighbor.
         attribute mapping can be used when you want to apply
         attribute to BGPUpdate under specific conditions.
 <at>  <at>  -537,6 +538,12  <at>  <at>  class BGPSpeaker(object):
         before paths are advertised. All the items in the list must
         be an instance of AttributeMap class

+        ``route_dist`` specifies route dist in which attribute_maps
+        are added.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be RF_VPN_V4 or RF_VPN_V6.
+
         We can set AttributeMap to a neighbor as follows;

           pref_filter = PrefixFilter('192.168.103.0/30',
 <at>  <at>  -549,24 +556,42  <at>  <at>  class BGPSpeaker(object):

         """

+        assert route_family in (RF_VPN_V4, RF_VPN_V6),\
+            'route_family must be RF_VPN_V4 or RF_VPN_V6'
+
         func_name = 'neighbor.attribute_map.set'
         param = {}
         param[neighbors.IP_ADDRESS] = address
         param[neighbors.ATTRIBUTE_MAP] = attribute_maps
+        if route_dist is not None:
+            param[vrfs.ROUTE_DISTINGUISHER] = route_dist
+            param[vrfs.VRF_RF] = route_family
         call(func_name, **param)

-    def attribute_map_get(self, address):
+    def attribute_map_get(self, address, route_dist=None,
+                          route_family=RF_VPN_V4):
         """This method gets in-bound filters of the specified neighbor.

         ``address`` specifies the IP address of the neighbor.

+        ``route_dist`` specifies route distinguisher that has attribute_maps.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be RF_VPN_V4 or RF_VPN_V6.
+
         Returns a list object containing an instance of AttributeMap

         """

+        assert route_family in (RF_VPN_V4, RF_VPN_V6),\
+            'route_family must be RF_VPN_V4 or RF_VPN_V6'
+
         func_name = 'neighbor.attribute_map.get'
         param = {}
         param[neighbors.IP_ADDRESS] = address
+        if route_dist is not None:
+            param[vrfs.ROUTE_DISTINGUISHER] = route_dist
+            param[vrfs.VRF_RF] = route_family
         attribute_maps = call(func_name, **param)
         return attribute_maps

diff --git a/ryu/services/protocols/bgp/constants.py b/ryu/services/protocols/bgp/constants.py
index b1af9b0..bda55f0 100644
--- a/ryu/services/protocols/bgp/constants.py
+++ b/ryu/services/protocols/bgp/constants.py
 <at>  <at>  -48,3 +48,9  <at>  <at>  VRF_TABLE = 'vrf_table'
 # RTC EOR timer default value
 # Time to wait for RTC-EOR, before we can send initial UPDATE as per RFC
 RTC_EOR_DEFAULT_TIME = 60
+
+# Constants for AttributeMaps
+ATTR_MAPS_ORG_KEY = '__orig'
+ATTR_MAPS_LABEL_KEY = 'at_maps_key'
+ATTR_MAPS_LABEL_DEFAULT = 'default'
+ATTR_MAPS_VALUE = 'at_maps'
diff --git a/ryu/services/protocols/bgp/core_managers/configuration_manager.py b/ryu/services/protocols/bgp/core_managers/configuration_manager.py
index ffac9bc..ff3dd3b 100644
--- a/ryu/services/protocols/bgp/core_managers/configuration_manager.py
+++ b/ryu/services/protocols/bgp/core_managers/configuration_manager.py
 <at>  <at>  -94,6 +94,14  <at>  <at>  class ConfigurationManager(CommonConfListener, VrfsConfListener,

         self._signal_bus.vrf_removed(vrf_conf.route_dist)

+        # Remove AttributeMaps under the removed vrf
+        rd = vrf_conf.route_dist
+        rf = vrf_conf.route_family
+        peers = self._peer_manager.iterpeers
+        for peer in peers:
+            key = ':'.join([rd, rf])
+            peer.attribute_maps.pop(key, None)
+
     def on_add_vrf_conf(self, evt):
         """Event handler for new VrfConf.

diff --git a/ryu/services/protocols/bgp/info_base/base.py b/ryu/services/protocols/bgp/info_base/base.py
index 13f02ca..0e56bd0 100644
--- a/ryu/services/protocols/bgp/info_base/base.py
+++ b/ryu/services/protocols/bgp/info_base/base.py
 <at>  <at>  -947,14 +947,14  <at>  <at>  class PrefixFilter(Filter):
         ge and le condition,
         this method returns True as the matching result.

-        ``prefix`` specifies the prefix. prefix must be string.
+        ``path`` specifies the path that has prefix.

         """
-        prefix = path.nlri
+        nlri = path.nlri

         result = False
-        length = prefix.length
-        net = netaddr.IPNetwork(prefix.formatted_nlri_str)
+        length = nlri.length
+        net = netaddr.IPNetwork(nlri.prefix)

         if net in self._network:
             if self._ge is None and self._le is None:
diff --git a/ryu/services/protocols/bgp/peer.py b/ryu/services/protocols/bgp/peer.py
index 1461852..598e593 100644
--- a/ryu/services/protocols/bgp/peer.py
+++ b/ryu/services/protocols/bgp/peer.py
 <at>  <at>  -37,6 +37,9  <at>  <at>  from ryu.services.protocols.bgp.rtconf.neighbors import NeighborConfListener
 from ryu.services.protocols.bgp.signals.emit import BgpSignalBus
 from ryu.services.protocols.bgp.speaker import BgpProtocol
 from ryu.services.protocols.bgp.info_base.ipv4 import Ipv4Path
+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.rtconf.vrfs import VRF_RF_IPV4, VRF_RF_IPV6
 from ryu.services.protocols.bgp.utils import bgp as bgp_utils
 from ryu.services.protocols.bgp.utils.evtlet import EventletIOFactory
 from ryu.services.protocols.bgp.utils import stats
 <at>  <at>  -415,15 +418,18  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):

      <at> property
     def attribute_maps(self):
-        return self._attribute_maps['__orig']\
-            if '__orig' in self._attribute_maps else []
+        return self._attribute_maps

      <at> attribute_maps.setter
     def attribute_maps(self, attribute_maps):
         _attr_maps = {}
-        _attr_maps.setdefault('__orig', [])
+        _attr_maps.setdefault(const.ATTR_MAPS_ORG_KEY, [])

-        for a in attribute_maps:
+        # key is 'default' or rd_rf that represents RD and route_family
+        key = attribute_maps[const.ATTR_MAPS_LABEL_KEY]
+        at_maps = attribute_maps[const.ATTR_MAPS_VALUE]
+
+        for a in at_maps:
             cloned = a.clone()
             LOG.debug("AttributeMap attr_type: %s, attr_value: %s",
                       cloned.attr_type, cloned.attr_value)
 <at>  <at>  -431,9 +437,9  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):
             attr_list.append(cloned)

             # preserve original order of attribute_maps
-            _attr_maps['__orig'].append(cloned)
+            _attr_maps[const.ATTR_MAPS_ORG_KEY].append(cloned)

-        self._attribute_maps = _attr_maps
+        self._attribute_maps[key] = _attr_maps
         self.on_update_attribute_maps()

     def is_mpbgp_cap_valid(self, route_family):
 <at>  <at>  -908,20 +914,19  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):
                 # attribute_maps and set local-pref value.
                 # If the path doesn't match, we set default local-pref 100.
                 localpref_attr = BGPPathAttributeLocalPref(100)
-                # TODO handle VPNv4Path
-                if isinstance(path, Ipv4Path):
-                    if AttributeMap.ATTR_LOCAL_PREF in self._attribute_maps:
-                        maps = \
-                            self._attribute_maps[AttributeMap.ATTR_LOCAL_PREF]
-                        for m in maps:
-                            cause, result = m.evaluate(path)
-                            LOG.debug(
-                                "local_pref evaluation result:%s, cause:%s",
-                                result, cause)
-
-                            if result:
-                                localpref_attr = m.get_attribute()
-                                break
+                key = const.ATTR_MAPS_LABEL_DEFAULT
+
+                if isinstance(path, (Vpnv4Path, Vpnv6Path)):
+                    nlri = nlri_list[0]
+                    rf = VRF_RF_IPV4 if isinstance(path, Vpnv4Path)\
+                        else VRF_RF_IPV6
+                    key = ':'.join([nlri.route_dist, rf])
+
+                attr_type = AttributeMap.ATTR_LOCAL_PREF
+                at_maps = self._attribute_maps.get(key, {})
+                result = self._lookup_attribute_map(at_maps, attr_type, path)
+                if result:
+                    localpref_attr = result

             # COMMUNITY Attribute.
             community_attr = pathattr_map.get(BGP_ATTR_TYPE_COMMUNITIES)
 <at>  <at>  -1972,3 +1977,18  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):
             if self._neigh_conf.enabled:
                 if not self._connect_retry_event.is_set():
                     self._connect_retry_event.set()
+
+     <at> staticmethod
+    def _lookup_attribute_map(attribute_map, attr_type, path):
+        result_attr = None
+        if attr_type in attribute_map:
+            maps = attribute_map[attr_type]
+            for m in maps:
+                cause, result = m.evaluate(path)
+                LOG.debug(
+                    "local_pref evaluation result:%s, cause:%s",
+                    result, cause)
+                if result:
+                    result_attr = m.get_attribute()
+                    break
+        return result_attr
--

-- 
1.8.5.2 (Apple Git-48)

------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
Hiroshi Yokoi | 18 Sep 14:03 2014
Picon

[PATCH] bgp: local preference support IPv6, VPNv4/v6 route family

local preference supports IPv6 and VPNv4/v6 route family.

Signed-off-by: Hiroshi Yokoi <yokoi.hiroshi@...>
---
 ryu/services/protocols/bgp/api/rtconf.py           | 44 +++++++++++++---
 ryu/services/protocols/bgp/bgpspeaker.py           | 28 +++++++++-
 ryu/services/protocols/bgp/constants.py            |  6 +++
 .../bgp/core_managers/configuration_manager.py     |  8 +++
 ryu/services/protocols/bgp/info_base/base.py       |  8 +--
 ryu/services/protocols/bgp/peer.py                 | 60 ++++++++++++++--------
 6 files changed, 120 insertions(+), 34 deletions(-)

diff --git a/ryu/services/protocols/bgp/api/rtconf.py b/ryu/services/protocols/bgp/api/rtconf.py
index ce98903..1d7e58e 100644
--- a/ryu/services/protocols/bgp/api/rtconf.py
+++ b/ryu/services/protocols/bgp/api/rtconf.py
 <at>  <at>  -29,6 +29,7  <at>  <at>  from ryu.services.protocols.bgp.rtconf.vrfs import ROUTE_DISTINGUISHER
 from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF
 from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4
 from ryu.services.protocols.bgp.rtconf.vrfs import VrfConf
+from ryu.services.protocols.bgp import constants as const

 LOG = logging.getLogger('bgpspeaker.api.rtconf')

 <at>  <at>  -152,22 +153,49  <at>  <at>  def set_neighbor_in_filter(neigh_ip_address, filters):

  <at> RegisterWithArgChecks(name='neighbor.attribute_map.set',
                        req_args=[neighbors.IP_ADDRESS,
-                                 neighbors.ATTRIBUTE_MAP])
-def set_neighbor_attribute_map(neigh_ip_address, attribute_maps):
-    """Returns a neighbor attribute_map for given ip address if exists."""
+                                 neighbors.ATTRIBUTE_MAP],
+                       opt_args=[ROUTE_DISTINGUISHER, VRF_RF])
+def set_neighbor_attribute_map(neigh_ip_address, at_maps,
+                               route_dist=None, route_family=VRF_RF_IPV4):
+    """set attribute_maps to the neighbor."""
     core = CORE_MANAGER.get_core_service()
     peer = core.peer_manager.get_by_addr(neigh_ip_address)
-    peer.attribute_maps = attribute_maps
+
+    at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT
+    at_maps_dict = {}
+
+    if route_dist is not None:
+        vrf_conf = CORE_MANAGER.vrfs_conf.get_vrf_conf(route_dist, route_family)
+        if vrf_conf:
+            at_maps_key = ':'.join([route_dist, route_family])
+        else:
+            raise RuntimeConfigError(desc='No VrfConf with rd %s' %
+                                 route_dist)
+
+    at_maps_dict[const.ATTR_MAPS_LABEL_KEY] = at_maps_key
+    at_maps_dict[const.ATTR_MAPS_VALUE] = at_maps
+    peer.attribute_maps = at_maps_dict
+
     return True

 
  <at> RegisterWithArgChecks(name='neighbor.attribute_map.get',
-                       req_args=[neighbors.IP_ADDRESS])
-def get_neighbor_attribute_map(neigh_ip_address):
+                       req_args=[neighbors.IP_ADDRESS],
+                       opt_args=[ROUTE_DISTINGUISHER, VRF_RF])
+def get_neighbor_attribute_map(neigh_ip_address,route_dist=None,
+                               route_family=VRF_RF_IPV4):
     """Returns a neighbor attribute_map for given ip address if exists."""
     core = CORE_MANAGER.get_core_service()
-    ret = core.peer_manager.get_by_addr(neigh_ip_address).attribute_maps
-    return ret
+    peer = core.peer_manager.get_by_addr(neigh_ip_address)
+    at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT
+
+    if route_dist is not None:
+        at_maps_key = ':'.join([route_dist, route_family])
+    at_maps = peer.attribute_maps.get(at_maps_key)
+    if at_maps:
+        return at_maps.get(const.ATTR_MAPS_ORG_KEY)
+    else:
+        return []

 # =============================================================================
 # VRF configuration related APIs
diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py
index 9844e08..3ef59ea 100644
--- a/ryu/services/protocols/bgp/bgpspeaker.py
+++ b/ryu/services/protocols/bgp/bgpspeaker.py
 <at>  <at>  -526,7 +526,8  <at>  <at>  class BGPSpeaker(object):
         param['port'] = port
         call(func_name, **param)

-    def attribute_map_set(self, address, attribute_maps):
+    def attribute_map_set(self, address, attribute_maps,
+                          route_dist=None, route_family=RF_VPN_V4):
         """This method sets attribute mapping to a neighbor.
         attribute mapping can be used when you want to apply
         attribute to BGPUpdate under specific conditions.
 <at>  <at>  -537,6 +538,12  <at>  <at>  class BGPSpeaker(object):
         before paths are advertised. All the items in the list must
         be an instance of AttributeMap class

+        ``route_dist`` specifies route dist in which attribute_maps
+        are added.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be RF_VPN_V4 or RF_VPN_V6.
+
         We can set AttributeMap to a neighbor as follows;

           pref_filter = PrefixFilter('192.168.103.0/30',
 <at>  <at>  -549,24 +556,41  <at>  <at>  class BGPSpeaker(object):

         """

+        assert route_family in (RF_VPN_V4, RF_VPN_V6),\
+            'route_family must be RF_VPN_V4 or RF_VPN_V6'
+
         func_name = 'neighbor.attribute_map.set'
         param = {}
         param[neighbors.IP_ADDRESS] = address
         param[neighbors.ATTRIBUTE_MAP] = attribute_maps
+        if route_dist is not None:
+            param[vrfs.ROUTE_DISTINGUISHER] = route_dist
+            param[vrfs.VRF_RF] = route_family
         call(func_name, **param)

-    def attribute_map_get(self, address):
+    def attribute_map_get(self, address, route_dist=None, route_family=RF_VPN_V4):
         """This method gets in-bound filters of the specified neighbor.

         ``address`` specifies the IP address of the neighbor.

+        ``route_dist`` specifies route distinguisher that has attribute_maps.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be RF_VPN_V4 or RF_VPN_V6.
+
         Returns a list object containing an instance of AttributeMap

         """

+        assert route_family in (RF_VPN_V4, RF_VPN_V6),\
+            'route_family must be RF_VPN_V4 or RF_VPN_V6'
+
         func_name = 'neighbor.attribute_map.get'
         param = {}
         param[neighbors.IP_ADDRESS] = address
+        if route_dist is not None:
+            param[vrfs.ROUTE_DISTINGUISHER] = route_dist
+            param[vrfs.VRF_RF] = route_family
         attribute_maps = call(func_name, **param)
         return attribute_maps

diff --git a/ryu/services/protocols/bgp/constants.py b/ryu/services/protocols/bgp/constants.py
index b1af9b0..31c88fc 100644
--- a/ryu/services/protocols/bgp/constants.py
+++ b/ryu/services/protocols/bgp/constants.py
 <at>  <at>  -48,3 +48,9  <at>  <at>  VRF_TABLE = 'vrf_table'
 # RTC EOR timer default value
 # Time to wait for RTC-EOR, before we can send initial UPDATE as per RFC
 RTC_EOR_DEFAULT_TIME = 60
+
+# Constants for AttributeMaps
+ATTR_MAPS_ORG_KEY = '__orig'
+ATTR_MAPS_LABEL_KEY = 'at_maps_key'
+ATTR_MAPS_LABEL_DEFAULT = 'default'
+ATTR_MAPS_VALUE = 'at_maps'
\ No newline at end of file
diff --git a/ryu/services/protocols/bgp/core_managers/configuration_manager.py b/ryu/services/protocols/bgp/core_managers/configuration_manager.py
index ffac9bc..ff3dd3b 100644
--- a/ryu/services/protocols/bgp/core_managers/configuration_manager.py
+++ b/ryu/services/protocols/bgp/core_managers/configuration_manager.py
 <at>  <at>  -94,6 +94,14  <at>  <at>  class ConfigurationManager(CommonConfListener, VrfsConfListener,

         self._signal_bus.vrf_removed(vrf_conf.route_dist)

+        # Remove AttributeMaps under the removed vrf
+        rd = vrf_conf.route_dist
+        rf = vrf_conf.route_family
+        peers = self._peer_manager.iterpeers
+        for peer in peers:
+            key = ':'.join([rd, rf])
+            peer.attribute_maps.pop(key, None)
+
     def on_add_vrf_conf(self, evt):
         """Event handler for new VrfConf.

diff --git a/ryu/services/protocols/bgp/info_base/base.py b/ryu/services/protocols/bgp/info_base/base.py
index 13f02ca..0e56bd0 100644
--- a/ryu/services/protocols/bgp/info_base/base.py
+++ b/ryu/services/protocols/bgp/info_base/base.py
 <at>  <at>  -947,14 +947,14  <at>  <at>  class PrefixFilter(Filter):
         ge and le condition,
         this method returns True as the matching result.

-        ``prefix`` specifies the prefix. prefix must be string.
+        ``path`` specifies the path that has prefix.

         """
-        prefix = path.nlri
+        nlri = path.nlri

         result = False
-        length = prefix.length
-        net = netaddr.IPNetwork(prefix.formatted_nlri_str)
+        length = nlri.length
+        net = netaddr.IPNetwork(nlri.prefix)

         if net in self._network:
             if self._ge is None and self._le is None:
diff --git a/ryu/services/protocols/bgp/peer.py b/ryu/services/protocols/bgp/peer.py
index 1461852..2418386 100644
--- a/ryu/services/protocols/bgp/peer.py
+++ b/ryu/services/protocols/bgp/peer.py
 <at>  <at>  -37,6 +37,9  <at>  <at>  from ryu.services.protocols.bgp.rtconf.neighbors import NeighborConfListener
 from ryu.services.protocols.bgp.signals.emit import BgpSignalBus
 from ryu.services.protocols.bgp.speaker import BgpProtocol
 from ryu.services.protocols.bgp.info_base.ipv4 import Ipv4Path
+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.rtconf.vrfs import VRF_RF_IPV4, VRF_RF_IPV6
 from ryu.services.protocols.bgp.utils import bgp as bgp_utils
 from ryu.services.protocols.bgp.utils.evtlet import EventletIOFactory
 from ryu.services.protocols.bgp.utils import stats
 <at>  <at>  -415,15 +418,18  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):

      <at> property
     def attribute_maps(self):
-        return self._attribute_maps['__orig']\
-            if '__orig' in self._attribute_maps else []
+        return self._attribute_maps

      <at> attribute_maps.setter
     def attribute_maps(self, attribute_maps):
         _attr_maps = {}
-        _attr_maps.setdefault('__orig', [])
+        _attr_maps.setdefault(const.ATTR_MAPS_ORG_KEY, [])

-        for a in attribute_maps:
+        # key is 'default' or rd_rf that represents RD and route_family
+        key = attribute_maps[const.ATTR_MAPS_LABEL_KEY]
+        at_maps = attribute_maps[const.ATTR_MAPS_VALUE]
+
+        for a in at_maps:
             cloned = a.clone()
             LOG.debug("AttributeMap attr_type: %s, attr_value: %s",
                       cloned.attr_type, cloned.attr_value)
 <at>  <at>  -431,9 +437,9  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):
             attr_list.append(cloned)

             # preserve original order of attribute_maps
-            _attr_maps['__orig'].append(cloned)
+            _attr_maps[const.ATTR_MAPS_ORG_KEY].append(cloned)

-        self._attribute_maps = _attr_maps
+        self._attribute_maps[key] = _attr_maps
         self.on_update_attribute_maps()

     def is_mpbgp_cap_valid(self, route_family):
 <at>  <at>  -908,20 +914,19  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):
                 # attribute_maps and set local-pref value.
                 # If the path doesn't match, we set default local-pref 100.
                 localpref_attr = BGPPathAttributeLocalPref(100)
-                # TODO handle VPNv4Path
-                if isinstance(path, Ipv4Path):
-                    if AttributeMap.ATTR_LOCAL_PREF in self._attribute_maps:
-                        maps = \
-                            self._attribute_maps[AttributeMap.ATTR_LOCAL_PREF]
-                        for m in maps:
-                            cause, result = m.evaluate(path)
-                            LOG.debug(
-                                "local_pref evaluation result:%s, cause:%s",
-                                result, cause)
-
-                            if result:
-                                localpref_attr = m.get_attribute()
-                                break
+                key = const.ATTR_MAPS_LABEL_DEFAULT
+
+                if isinstance(path, (Vpnv4Path, Vpnv6Path)):
+                    nlri = nlri_list[0]
+                    rf = VRF_RF_IPV4 if isinstance(path, Vpnv4Path)\
+                        else VRF_RF_IPV6
+                    key = ':'.join([nlri.route_dist, rf])
+
+                attr_type = AttributeMap.ATTR_LOCAL_PREF
+                at_maps = self._attribute_maps.get(key, {})
+                result = self._lookup_attribute_map(at_maps, attr_type, path)
+                if result:
+                    localpref_attr = result

             # COMMUNITY Attribute.
             community_attr = pathattr_map.get(BGP_ATTR_TYPE_COMMUNITIES)
 <at>  <at>  -1972,3 +1977,18  <at>  <at>  class Peer(Source, Sink, NeighborConfListener, Activity):
             if self._neigh_conf.enabled:
                 if not self._connect_retry_event.is_set():
                     self._connect_retry_event.set()
+
+     <at> staticmethod
+    def _lookup_attribute_map(attribute_map, attr_type, path):
+        result_attr = None
+        if attr_type in attribute_map:
+            maps = attribute_map[attr_type]
+            for m in maps:
+                cause, result = m.evaluate(path)
+                LOG.debug(
+                    "local_pref evaluation result:%s, cause:%s",
+                    result, cause)
+                if result:
+                    result_attr = m.get_attribute()
+                    break
+        return result_attr
\ No newline at end of file
--

-- 
1.8.5.2 (Apple Git-48)

------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
Sriram | 18 Sep 02:12 2014
Picon

Patch for Missing fields in StatsReply messages in OF 1.2, 1.3

Hi,

I found some fields missing in the OpenFlow statistics messages in both OpenFlow 1.2 and 1.3 lib files. I also removed extra fields that are not part of 1.2 header. Unit tests are passing.

Hope this is helpful.

Thanks,
Sriram
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
A G | 16 Sep 16:06 2014
Picon

Ryu/base/app_manager.py - send_request & reply_to_request methods?

Hi Folks,

I really like Ryu, the framework is all there, I just make the apps.

Issues: When my Ryu application fails the framework continues to operate, the connection from the switches to the controller is still kept alive by the framework. (Which is fine) However, when the application that fails is responsible for L2 switching functions, I'd like for the underlying framework to either close the switch(es)/controller connection or to stop the Ryu framework so that the echo's from the switches aren't replied to by the controller, or some other implementation that would signal to the switches that the controller is broken.

The reason for this functionality is that the brand of switches that were testing/using with SDN have a "fail-standalone" mode that reverts back to a traditional switch when the connection to the controller is lost or closed.

Question:
  • Can I somehow use the app_manager.send_event method to have the framework send a message to an application, and then have the application reply to show that it has completed what it needed to do / is still operating?
    • If yes, can you provide an example of doing so with the simple_switch module?
    • If no, do you have any other suggestions for implementing this functionality?

------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce.
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Gmane