Yusuke Iwase | 20 Aug 07:27 2014
Picon

[PATCH] ofctl_rest: support OFPFlowStats filtered by fields

this patch enables ofctl_rest to get OFPFlowStats messages
filtered by the OFPFlowStatsRequest fields in OpenFlow specification.

usage)

  URI:    /stats/flow/≤dpid>
  method: POST

  the message body is as follows:

  table_id     ID of table.
  out_port     Require matching entries to include this as an output port.
  out_group    Require matching entries to include this as an output group.
               (Not supported in of1.0)
  cookie       Require matching entries to contain this cookie value.
               (Not supported in of1.0)
  cookie_mask  Mask used to restrict the cookie bits that must match.
               (Not supported in of1.0)
  match        Fields to match.

e.g.)

  curl -X POST -d '{"table_id": 0,
                    "out_port": 2,
                    "cookie": 1,
                    "cookie_mask": 1,
                    "match":{"in_port":1}}'
  http://localhost:8080/stats/flow/1

Signed-off-by: IWASE Yusuke <iwase.yusuke0@...>
(Continue reading)

Sujit Pandey | 19 Aug 23:01 2014
Picon

about adding mpls flow

Hi 
I am trying to put mpls flows in the some topology where shortest path is selected. for selecting the path I am using the networkx and output be the list.

LOG = logging.getLogger(__name__)


class SwitchEventHandler(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
    _CONTEXTS={ 'dpset': dpset.DPSet,}
    list={'00:00:00:00:00:01':1,'00:00:00:00:00:02':2,'00:00:00:00:00:03':3}
def __init__(self, *args, **kwargs):
        super(SwitchEventHandler, self).__init__(*args, **kwargs)
        self.mac_to_port = {}
        self.dpset = kwargs['dpset']
        self.link_list = []
        self.s=[]
  <at> set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        match = parser.OFPMatch()
        actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                          ofproto.OFPCML_NO_BUFFER)]
        self.add_flow(datapath, 0, match, actions)

    def add_flow(self, datapath, priority, match, actions):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
         inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)]

        mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
                                match=match, instructions=inst)
        datapath.send_msg(mod)
          <at> set_ev_cls(ofp_event.EventOFPErrorMsg, [HANDSHAKE_DISPATCHER, CONFIG_DISPA$
    def error_msg_handler(self, ev):
        msg = ev.msg
        self.logger.debug('OFPErrorMsg received: type=0x%02x code=0x%02x ''mess$

    <at> handler.set_ev_cls(event.EventLinkAdd)
    def link_add_handler(self, ev):
        self.s.append((ev.link.src.dpid,ev.link.src.port_no,ev.link.dst.dpid,ev))
        for i in self.s:
            self.link_list.append(i)

here i can get the dpid and port no.
but I am missing host connecting port. how do I  get this?
second the shortest path will be like x=[1,2,5].
then how to get the associate port_no.? 
again I have to split the path for adding seperate flows like (in_port,1,out_port that is connected to 2),(in_port connected to 1,2,out_port connected to 5) and so on for adding flows.
how can i break and retrieve information?

 thank you






--
Best regards

Sujit Pandey
------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Hiroshi Yokoi | 19 Aug 09:42 2014
Picon

[PATCH] bgp: reduce duplicate codes with helper_function.

reduced duplicate codes and put together to a static function.

Signed-off-by: Hiroshi Yokoi <yokoi.hiroshi@...>
---
 ryu/services/protocols/bgp/bgpspeaker.py | 50 +++++++++++++++++---------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py
index 73899aa..c88a972 100644
--- a/ryu/services/protocols/bgp/bgpspeaker.py
+++ b/ryu/services/protocols/bgp/bgpspeaker.py
 <at>  <at>  -312,21 +312,14  <at>  <at>  class BGPSpeaker(object):
             func_name = 'prefix.add_local'
             networks[ROUTE_DISTINGUISHER] = route_dist

-            # check if the prefix address is IPv6 address
-            ip, masklen = prefix.split('/')
-            if netaddr.valid_ipv6(ip):
-                networks[ROUTE_FAMILY] = vrfs.VRF_RF_IPV6
-                # convert the next_hop address to IPv4-Mapped IPv6 Address
-                # if it is IPv4 address
-                if netaddr.valid_ipv4(next_hop):
-                    networks[NEXT_HOP] = \
-                        str(netaddr.IPAddress(next_hop).ipv6())
-
-                # normalize IPv6 address expression
-                networks[PREFIX] = \
-                    str(netaddr.IPAddress(ip)) + '/' + masklen
-            else:
-                networks[ROUTE_FAMILY] = vrfs.VRF_RF_IPV4
+            rf, p = self._check_rf_and_normalize(prefix)
+            networks[ROUTE_FAMILY] = rf
+            networks[PREFIX] = p
+
+            if rf == vrfs.VRF_RF_IPV6 and netaddr.valid_ipv4(next_hop):
+                # convert the next_hop to IPv4-Mapped IPv6 Address
+                networks[NEXT_HOP] = \
+                    str(netaddr.IPAddress(next_hop).ipv6())

         call(func_name, **networks)

 <at>  <at>  -348,14 +341,9  <at>  <at>  class BGPSpeaker(object):
             func_name = 'prefix.delete_local'
             networks[ROUTE_DISTINGUISHER] = route_dist

-            ip, masklen = prefix.split('/')
-            if netaddr.valid_ipv6(ip):
-                networks[ROUTE_FAMILY] = vrfs.VRF_RF_IPV6
-                # normalize IPv6 address expression
-                networks[PREFIX] = \
-                    str(netaddr.IPAddress(ip)) + '/' + masklen
-            else:
-                networks[ROUTE_FAMILY] = vrfs.VRF_RF_IPV4
+            rf, p = self._check_rf_and_normalize(prefix)
+            networks[ROUTE_FAMILY] = rf
+            networks[PREFIX] = p

         call(func_name, **networks)

 <at>  <at>  -535,3 +523,19  <at>  <at>  class BGPSpeaker(object):
         param['host'] = address
         param['port'] = port
         call(func_name, **param)
+
+     <at> staticmethod
+    def _check_rf_and_normalize(prefix):
+        """ check prefix's route_family and if the address is
+        IPv6 address, return IPv6 route_family and normalized IPv6 address.
+        If the address is IPv4 address, return IPv4 route_family
+        and the prefix itself.
+
+        """
+        ip, masklen = prefix.split('/')
+        if netaddr.valid_ipv6(ip):
+            # normalize IPv6 address
+            ipv6_prefix = str(netaddr.IPAddress(ip)) + '/' + masklen
+            return vrfs.VRF_RF_IPV6, ipv6_prefix
+        else:
+            return vrfs.VRF_RF_IPV4, prefix
--

-- 
1.8.5.2 (Apple Git-48)

------------------------------------------------------------------------------
ISHIDA Wataru | 18 Aug 07:44 2014
Picon

[PATCH] bmpstation: make configurable through environment variables

you can specify listening HOST and PORT by setting env variable
'RYU_BMP_SERVER_HOST' and 'RYU_BMP_SERVER_PORT'.

'RYU_BMP_OUTPUT_FILE' specifes the output file name
'RYU_BMP_FAILED_DUMP' specifes the file name of the error dump

Signed-off-by: ISHIDA Wataru <ishida.wataru@...>
---
 ryu/app/bmpstation.py |   50 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 11 deletions(-)

diff --git a/ryu/app/bmpstation.py b/ryu/app/bmpstation.py
index 67c069c..f8d22de 100644
--- a/ryu/app/bmpstation.py
+++ b/ryu/app/bmpstation.py
 <at>  <at>  -13,9 +13,9  <at>  <at> 
 # See the License for the specific language governing permissions and
 # limitations under the License.

+import os
 import socket
-import logging
-logging.basicConfig(level=logging.DEBUG)
+import time

 from ryu.base import app_manager

 <at>  <at>  -23,23 +23,32  <at>  <at>  from ryu.lib import hub
 from ryu.lib.hub import StreamServer
 from ryu.lib.packet import bmp

-SERVER_HOST = '0.0.0.0'
-SERVER_PORT = 11019
-

 class BMPStation(app_manager.RyuApp):
     def __init__(self):
         super(BMPStation, self).__init__()
         self.name = 'bmpstation'
+        self.server_host = os.environ.get('RYU_BMP_SERVER_HOST', '0.0.0.0')
+        self.server_port = int(os.environ.get('RYU_BMP_SERVER_PORT', 11019))
+        output_file = os.environ.get('RYU_BMP_OUTPUT_FILE', 'ryu_bmp.log')
+        failed_dump = os.environ.get('RYU_BMP_FAILED_DUMP',
+                                     'ryu_bmp_failed.dump')
+
+        self.output_fd = open(output_file, 'w')
+        self.failed_dump_fd = open(failed_dump, 'w')
+
+        self.failed_pkt_count = 0

     def start(self):
         super(BMPStation, self).start()
+        self.logger.debug("listening on %s:%s" % (self.server_host,
+                                                  self.server_port))

-        return hub.spawn(StreamServer((SERVER_HOST, SERVER_PORT),
+        return hub.spawn(StreamServer((self.server_host, self.server_port),
                                       self.loop).serve_forever)

     def loop(self, sock, addr):
-        logging.debug("started bmp loop.")
+        self.logger.debug("start bmp loop: client %s" % str(addr))
         is_active = True
         buf = bytearray()
         required_len = bmp.BMPMessage._HDR_LEN
 <at>  <at>  -53,7 +62,7  <at>  <at>  class BMPStation(app_manager.RyuApp):
             while len(buf) >= required_len:
                 version, len_, _ = bmp.BMPMessage.parse_header(buf)
                 if version != bmp.VERSION:
-                    logging.error("unsupported bmp version: %d" % version)
+                    self.logger.error("unsupported bmp version: %d" % version)
                     is_active = False
                     break

 <at>  <at>  -61,8 +70,27  <at>  <at>  class BMPStation(app_manager.RyuApp):
                 if len(buf) < required_len:
                     break

-                msg, rest = bmp.BMPMessage.parser(buf)
-                print msg, '\n'
+                try:
+                    msg, rest = bmp.BMPMessage.parser(buf)
+                except Exception, e:
+                    pkt = buf[:len_]
+                    self.failed_dump_fd.write(pkt)
+                    self.failed_dump_fd.flush()
+                    buf = buf[len_:]
+                    self.failed_pkt_count += 1
+                    self.logger.error("failed to parse: %s"
+                                      " (total fail count: %d)" %
+                                      (e, self.failed_pkt_count))
+                else:
+                    t = time.strftime("%Y %b %d %H:%M:%S", time.localtime())
+                    self.logger.debug("%s | %s\n" % (t, msg))
+                    self.output_fd.write("%s | %s\n\n" % (t, msg))
+                    self.output_fd.flush()
+                    buf = rest

-                buf = rest
                 required_len = bmp.BMPMessage._HDR_LEN
+
+        self.logger.debug("end bmp loop.")
+        sock.close()
+        self.output_fd.close()
+        self.failed_dump_fd.close()
--

-- 
1.7.10.4

------------------------------------------------------------------------------
ISHIDA Wataru | 18 Aug 02:19 2014
Picon

[PATCH 1/6] bgp: add support for RFC3107


Signed-off-by: ISHIDA Wataru <ishida.wataru@...>
---
 ryu/lib/packet/bgp.py             |   77 ++++++++++++++++++++++++++++---------
 ryu/lib/packet/safi.py            |    1 +
 ryu/tests/unit/packet/test_bgp.py |    6 +++
 3 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py
index ad08d9e..698d0fd 100644
--- a/ryu/lib/packet/bgp.py
+++ b/ryu/lib/packet/bgp.py
 <at>  <at>  -30,8 +30,8  <at>  <at>  import netaddr

 from ryu.ofproto.ofproto_parser import msg_pack_into
 from ryu.lib.stringify import StringifyMixin
-from ryu.lib.packet import afi
-from ryu.lib.packet import safi
+from ryu.lib.packet import afi as addr_family
+from ryu.lib.packet import safi as subaddr_family
 from ryu.lib.packet import packet_base
 from ryu.lib.packet import stream_parser
 from ryu.lib import addrconv
 <at>  <at>  -572,18 +572,23  <at>  <at>  class RouteFamily(StringifyMixin):
         return cmp((other.afi, other.safi), (self.afi, self.safi))

 # Route Family Singleton
-RF_IPv4_UC = RouteFamily(afi.IP, safi.UNICAST)
-RF_IPv6_UC = RouteFamily(afi.IP6, safi.UNICAST)
-RF_IPv4_VPN = RouteFamily(afi.IP, safi.MPLS_VPN)
-RF_IPv6_VPN = RouteFamily(afi.IP6, safi.MPLS_VPN)
-RF_RTC_UC = RouteFamily(afi.IP, safi.ROUTE_TARGET_CONSTRTAINS)
+RF_IPv4_UC = RouteFamily(addr_family.IP, subaddr_family.UNICAST)
+RF_IPv6_UC = RouteFamily(addr_family.IP6, subaddr_family.UNICAST)
+RF_IPv4_VPN = RouteFamily(addr_family.IP, subaddr_family.MPLS_VPN)
+RF_IPv6_VPN = RouteFamily(addr_family.IP6, subaddr_family.MPLS_VPN)
+RF_IPv4_MPLS = RouteFamily(addr_family.IP, subaddr_family.MPLS_LABEL)
+RF_IPv6_MPLS = RouteFamily(addr_family.IP6, subaddr_family.MPLS_LABEL)
+RF_RTC_UC = RouteFamily(addr_family.IP,
+                        subaddr_family.ROUTE_TARGET_CONSTRTAINS)

 _rf_map = {
-    (afi.IP, safi.UNICAST): RF_IPv4_UC,
-    (afi.IP6, safi.UNICAST): RF_IPv6_UC,
-    (afi.IP, safi.MPLS_VPN): RF_IPv4_VPN,
-    (afi.IP6, safi.MPLS_VPN): RF_IPv6_VPN,
-    (afi.IP, safi.ROUTE_TARGET_CONSTRTAINS): RF_RTC_UC
+    (addr_family.IP, subaddr_family.UNICAST): RF_IPv4_UC,
+    (addr_family.IP6, subaddr_family.UNICAST): RF_IPv6_UC,
+    (addr_family.IP, subaddr_family.MPLS_VPN): RF_IPv4_VPN,
+    (addr_family.IP6, subaddr_family.MPLS_VPN): RF_IPv6_VPN,
+    (addr_family.IP, subaddr_family.MPLS_LABEL): RF_IPv4_MPLS,
+    (addr_family.IP6, subaddr_family.MPLS_LABEL): RF_IPv6_MPLS,
+    (addr_family.IP, subaddr_family.ROUTE_TARGET_CONSTRTAINS): RF_RTC_UC
 }

 
 <at>  <at>  -803,9 +808,30  <at>  <at>  class _LabelledAddrPrefix(_AddrPrefix):
                             bytearray()) + cls._prefix_to_bin(rest))

      <at> classmethod
+    def _has_no_label(cls, bin_):
+        try:
+            length = len(bin_)
+            labels = []
+            while True:
+                (label, bin_) = cls._label_from_bin(bin_)
+                labels.append(label)
+                if label & 1:  # bottom of stack
+                    break
+            assert length > struct.calcsize(cls._LABEL_PACK_STR) * len(labels)
+        except struct.error:
+            return True
+        except AssertionError:
+            return True
+        return False
+
+     <at> classmethod
     def _from_bin(cls, addr):
         rest = addr
         labels = []
+
+        if cls._has_no_label(rest):
+            return ([],) + cls._prefix_from_bin(rest)
+
         while True:
             (label, rest) = cls._label_from_bin(rest)
             labels.append(label >> 4)
 <at>  <at>  -919,6 +945,14  <at>  <at>  class IP6AddrPrefix(_UnlabelledAddrPrefix, _IP6AddrPrefix):
         return self.prefix

 
+class LabelledIPAddrPrefix(_LabelledAddrPrefix, _IPAddrPrefix):
+    ROUTE_FAMILY = RF_IPv4_MPLS
+
+
+class LabelledIP6AddrPrefix(_LabelledAddrPrefix, _IP6AddrPrefix):
+    ROUTE_FAMILY = RF_IPv6_MPLS
+
+
 class LabelledVPNIPAddrPrefix(_LabelledAddrPrefix, _VPNAddrPrefix,
                               _IPAddrPrefix):
     ROUTE_FAMILY = RF_IPv4_VPN
 <at>  <at>  -1067,6 +1101,8  <at>  <at>  _addr_class_key = lambda x: (x.afi, x.safi)
 _ADDR_CLASSES = {
     _addr_class_key(RF_IPv4_UC): IPAddrPrefix,
     _addr_class_key(RF_IPv6_UC): IP6AddrPrefix,
+    _addr_class_key(RF_IPv4_MPLS): LabelledIPAddrPrefix,
+    _addr_class_key(RF_IPv6_MPLS): LabelledIP6AddrPrefix,
     _addr_class_key(RF_IPv4_VPN): LabelledVPNIPAddrPrefix,
     _addr_class_key(RF_IPv6_VPN): LabelledVPNIP6AddrPrefix,
     _addr_class_key(RF_RTC_UC): RouteTargetMembershipNLRI,
 <at>  <at>  -1937,10 +1973,12  <at>  <at>  class BGPPathAttributeMpReachNLRI(_PathAttribute):
         self.safi = safi
         self.next_hop_len = next_hop_len
         self.next_hop = next_hop
-        if RouteFamily(afi, safi) in (RF_IPv6_UC, RF_IPv6_VPN):
+        if afi == addr_family.IP:
+            self._next_hop_bin = addrconv.ipv4.text_to_bin(next_hop)
+        elif afi == addr_family.IP6:
             self._next_hop_bin = addrconv.ipv6.text_to_bin(next_hop)
         else:
-            self._next_hop_bin = addrconv.ipv4.text_to_bin(next_hop)
+            raise ValueError('Invalid address familly(%d)' % afi)
         self.reserved = reserved
         self.nlri = nlri
         addr_cls = _get_addr_class(afi, safi)
 <at>  <at>  -1963,16 +2001,19  <at>  <at>  class BGPPathAttributeMpReachNLRI(_PathAttribute):
             nlri.append(n)

         rf = RouteFamily(afi, safi)
-        if rf == RF_IPv6_UC:
-            next_hop = addrconv.ipv6.bin_to_text(next_hop_bin)
-        elif rf == RF_IPv6_VPN:
+        if rf == RF_IPv6_VPN:
             next_hop = addrconv.ipv6.bin_to_text(next_hop_bin[cls._rd_length:])
             next_hop_len -= cls._rd_length
         elif rf == RF_IPv4_VPN:
             next_hop = addrconv.ipv4.bin_to_text(next_hop_bin[cls._rd_length:])
             next_hop_len -= cls._rd_length
-        else:
+        elif afi == addr_family.IP:
             next_hop = addrconv.ipv4.bin_to_text(next_hop_bin)
+        elif afi == addr_family.IP6:
+            next_hop = addrconv.ipv6.bin_to_text(next_hop_bin)
+        else:
+            raise ValueError('Invalid address familly(%d)' % afi)
+
         return {
             'afi': afi,
             'safi': safi,
diff --git a/ryu/lib/packet/safi.py b/ryu/lib/packet/safi.py
index 9ac2bcb..fc3e0ac 100644
--- a/ryu/lib/packet/safi.py
+++ b/ryu/lib/packet/safi.py
 <at>  <at>  -21,5 +21,6  <at>  <at>  http://www.iana.org/assignments/safi-namespace/safi-namespace.xhtml

 UNICAST = 1
 MULTICAST = 2
+MPLS_LABEL = 4  # RFC 3107
 MPLS_VPN = 128  # RFC 4364
 ROUTE_TARGET_CONSTRTAINS = 132  # RFC 4684
diff --git a/ryu/tests/unit/packet/test_bgp.py b/ryu/tests/unit/packet/test_bgp.py
index b9201c1..b5f21dc 100644
--- a/ryu/tests/unit/packet/test_bgp.py
+++ b/ryu/tests/unit/packet/test_bgp.py
 <at>  <at>  -90,6 +90,9  <at>  <at>  class Test_bgp(unittest.TestCase):
                                         route_dist='10.0.0.1:10000',
                                         labels=[5, 6, 7, 8]),
         ]
+        mp_nlri2 = [
+            bgp.LabelledIPAddrPrefix(24, '192.168.0.0', labels=[1, 2, 3])
+        ]
         communities = [
             bgp.BGP_COMMUNITY_NO_EXPORT,
             bgp.BGP_COMMUNITY_NO_ADVERTISE,
 <at>  <at>  -126,6 +129,9  <at>  <at>  class Test_bgp(unittest.TestCase):
             bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_VPN,
                                             next_hop='1.1.1.1',
                                             nlri=mp_nlri),
+            bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_LABEL,
+                                            next_hop='1.1.1.1',
+                                            nlri=mp_nlri2),
             bgp.BGPPathAttributeMpUnreachNLRI(afi=afi.IP, safi=safi.MPLS_VPN,
                                               withdrawn_routes=mp_nlri),
             bgp.BGPPathAttributeUnknown(flags=0, type_=100, value=300 * 'bar')
--

-- 
1.7.10.4

------------------------------------------------------------------------------
ISHIDA Wataru | 18 Aug 00:30 2014
Picon

[PATCH 5/6] bgp: encode 'next_hop' in human readable format


Signed-off-by: ISHIDA Wataru <ishida.wataru@...>
---
 ryu/lib/packet/bgp.py |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py
index fb82412..ff6fdd0 100644
--- a/ryu/lib/packet/bgp.py
+++ b/ryu/lib/packet/bgp.py
 <at>  <at>  -1960,6 +1960,11  <at>  <at>  class BGPPathAttributeMpReachNLRI(_PathAttribute):
     _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL
     _class_suffixes = ['AddrPrefix']
     _rd_length = 8
+    _TYPE = {
+        'ascii': [
+            'next_hop'
+        ]
+    }

     def __init__(self, afi, safi, next_hop, nlri,
                  next_hop_len=0, reserved='\0',
--

-- 
1.7.10.4

------------------------------------------------------------------------------
ISHIDA Wataru | 17 Aug 19:45 2014
Picon

[PATCH 1/6] bgp: add support for RFC3107


Signed-off-by: ISHIDA Wataru <ishida.wataru@...>
---
 ryu/lib/packet/bgp.py  |   77 +++++++++++++++++++++++++++++++++++++-----------
 ryu/lib/packet/safi.py |    1 +
 2 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py
index ad08d9e..698d0fd 100644
--- a/ryu/lib/packet/bgp.py
+++ b/ryu/lib/packet/bgp.py
 <at>  <at>  -30,8 +30,8  <at>  <at>  import netaddr

 from ryu.ofproto.ofproto_parser import msg_pack_into
 from ryu.lib.stringify import StringifyMixin
-from ryu.lib.packet import afi
-from ryu.lib.packet import safi
+from ryu.lib.packet import afi as addr_family
+from ryu.lib.packet import safi as subaddr_family
 from ryu.lib.packet import packet_base
 from ryu.lib.packet import stream_parser
 from ryu.lib import addrconv
 <at>  <at>  -572,18 +572,23  <at>  <at>  class RouteFamily(StringifyMixin):
         return cmp((other.afi, other.safi), (self.afi, self.safi))

 # Route Family Singleton
-RF_IPv4_UC = RouteFamily(afi.IP, safi.UNICAST)
-RF_IPv6_UC = RouteFamily(afi.IP6, safi.UNICAST)
-RF_IPv4_VPN = RouteFamily(afi.IP, safi.MPLS_VPN)
-RF_IPv6_VPN = RouteFamily(afi.IP6, safi.MPLS_VPN)
-RF_RTC_UC = RouteFamily(afi.IP, safi.ROUTE_TARGET_CONSTRTAINS)
+RF_IPv4_UC = RouteFamily(addr_family.IP, subaddr_family.UNICAST)
+RF_IPv6_UC = RouteFamily(addr_family.IP6, subaddr_family.UNICAST)
+RF_IPv4_VPN = RouteFamily(addr_family.IP, subaddr_family.MPLS_VPN)
+RF_IPv6_VPN = RouteFamily(addr_family.IP6, subaddr_family.MPLS_VPN)
+RF_IPv4_MPLS = RouteFamily(addr_family.IP, subaddr_family.MPLS_LABEL)
+RF_IPv6_MPLS = RouteFamily(addr_family.IP6, subaddr_family.MPLS_LABEL)
+RF_RTC_UC = RouteFamily(addr_family.IP,
+                        subaddr_family.ROUTE_TARGET_CONSTRTAINS)

 _rf_map = {
-    (afi.IP, safi.UNICAST): RF_IPv4_UC,
-    (afi.IP6, safi.UNICAST): RF_IPv6_UC,
-    (afi.IP, safi.MPLS_VPN): RF_IPv4_VPN,
-    (afi.IP6, safi.MPLS_VPN): RF_IPv6_VPN,
-    (afi.IP, safi.ROUTE_TARGET_CONSTRTAINS): RF_RTC_UC
+    (addr_family.IP, subaddr_family.UNICAST): RF_IPv4_UC,
+    (addr_family.IP6, subaddr_family.UNICAST): RF_IPv6_UC,
+    (addr_family.IP, subaddr_family.MPLS_VPN): RF_IPv4_VPN,
+    (addr_family.IP6, subaddr_family.MPLS_VPN): RF_IPv6_VPN,
+    (addr_family.IP, subaddr_family.MPLS_LABEL): RF_IPv4_MPLS,
+    (addr_family.IP6, subaddr_family.MPLS_LABEL): RF_IPv6_MPLS,
+    (addr_family.IP, subaddr_family.ROUTE_TARGET_CONSTRTAINS): RF_RTC_UC
 }

 
 <at>  <at>  -803,9 +808,30  <at>  <at>  class _LabelledAddrPrefix(_AddrPrefix):
                             bytearray()) + cls._prefix_to_bin(rest))

      <at> classmethod
+    def _has_no_label(cls, bin_):
+        try:
+            length = len(bin_)
+            labels = []
+            while True:
+                (label, bin_) = cls._label_from_bin(bin_)
+                labels.append(label)
+                if label & 1:  # bottom of stack
+                    break
+            assert length > struct.calcsize(cls._LABEL_PACK_STR) * len(labels)
+        except struct.error:
+            return True
+        except AssertionError:
+            return True
+        return False
+
+     <at> classmethod
     def _from_bin(cls, addr):
         rest = addr
         labels = []
+
+        if cls._has_no_label(rest):
+            return ([],) + cls._prefix_from_bin(rest)
+
         while True:
             (label, rest) = cls._label_from_bin(rest)
             labels.append(label >> 4)
 <at>  <at>  -919,6 +945,14  <at>  <at>  class IP6AddrPrefix(_UnlabelledAddrPrefix, _IP6AddrPrefix):
         return self.prefix

 
+class LabelledIPAddrPrefix(_LabelledAddrPrefix, _IPAddrPrefix):
+    ROUTE_FAMILY = RF_IPv4_MPLS
+
+
+class LabelledIP6AddrPrefix(_LabelledAddrPrefix, _IP6AddrPrefix):
+    ROUTE_FAMILY = RF_IPv6_MPLS
+
+
 class LabelledVPNIPAddrPrefix(_LabelledAddrPrefix, _VPNAddrPrefix,
                               _IPAddrPrefix):
     ROUTE_FAMILY = RF_IPv4_VPN
 <at>  <at>  -1067,6 +1101,8  <at>  <at>  _addr_class_key = lambda x: (x.afi, x.safi)
 _ADDR_CLASSES = {
     _addr_class_key(RF_IPv4_UC): IPAddrPrefix,
     _addr_class_key(RF_IPv6_UC): IP6AddrPrefix,
+    _addr_class_key(RF_IPv4_MPLS): LabelledIPAddrPrefix,
+    _addr_class_key(RF_IPv6_MPLS): LabelledIP6AddrPrefix,
     _addr_class_key(RF_IPv4_VPN): LabelledVPNIPAddrPrefix,
     _addr_class_key(RF_IPv6_VPN): LabelledVPNIP6AddrPrefix,
     _addr_class_key(RF_RTC_UC): RouteTargetMembershipNLRI,
 <at>  <at>  -1937,10 +1973,12  <at>  <at>  class BGPPathAttributeMpReachNLRI(_PathAttribute):
         self.safi = safi
         self.next_hop_len = next_hop_len
         self.next_hop = next_hop
-        if RouteFamily(afi, safi) in (RF_IPv6_UC, RF_IPv6_VPN):
+        if afi == addr_family.IP:
+            self._next_hop_bin = addrconv.ipv4.text_to_bin(next_hop)
+        elif afi == addr_family.IP6:
             self._next_hop_bin = addrconv.ipv6.text_to_bin(next_hop)
         else:
-            self._next_hop_bin = addrconv.ipv4.text_to_bin(next_hop)
+            raise ValueError('Invalid address familly(%d)' % afi)
         self.reserved = reserved
         self.nlri = nlri
         addr_cls = _get_addr_class(afi, safi)
 <at>  <at>  -1963,16 +2001,19  <at>  <at>  class BGPPathAttributeMpReachNLRI(_PathAttribute):
             nlri.append(n)

         rf = RouteFamily(afi, safi)
-        if rf == RF_IPv6_UC:
-            next_hop = addrconv.ipv6.bin_to_text(next_hop_bin)
-        elif rf == RF_IPv6_VPN:
+        if rf == RF_IPv6_VPN:
             next_hop = addrconv.ipv6.bin_to_text(next_hop_bin[cls._rd_length:])
             next_hop_len -= cls._rd_length
         elif rf == RF_IPv4_VPN:
             next_hop = addrconv.ipv4.bin_to_text(next_hop_bin[cls._rd_length:])
             next_hop_len -= cls._rd_length
-        else:
+        elif afi == addr_family.IP:
             next_hop = addrconv.ipv4.bin_to_text(next_hop_bin)
+        elif afi == addr_family.IP6:
+            next_hop = addrconv.ipv6.bin_to_text(next_hop_bin)
+        else:
+            raise ValueError('Invalid address familly(%d)' % afi)
+
         return {
             'afi': afi,
             'safi': safi,
diff --git a/ryu/lib/packet/safi.py b/ryu/lib/packet/safi.py
index 9ac2bcb..fc3e0ac 100644
--- a/ryu/lib/packet/safi.py
+++ b/ryu/lib/packet/safi.py
 <at>  <at>  -21,5 +21,6  <at>  <at>  http://www.iana.org/assignments/safi-namespace/safi-namespace.xhtml

 UNICAST = 1
 MULTICAST = 2
+MPLS_LABEL = 4  # RFC 3107
 MPLS_VPN = 128  # RFC 4364
 ROUTE_TARGET_CONSTRTAINS = 132  # RFC 4684
--

-- 
1.7.10.4

------------------------------------------------------------------------------
Karthik Sharma | 16 Aug 10:38 2014
Picon

Mininet connecting to RYU controller

I start RYU controller which opens TCP listening port 6633.Now I connect my mininet topology to the controller port 6633.My mininet topology consists of 6 switches.Hence there will be 6 connections one from each switch to the RYU Controller port.

Now I bring down my controller and start the controller again.


I find that all the switches in my topology can talk to the controller as if the controller process were never killed.

This is not how I understand a TCP connection between a server and a client.If the server goes down I would expect the connection to be disconnected.

This set of connections seem to survive a server process restart.Can someone explain how this is happening?I am just curious

Thanks & Regards,
Karthik.

------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
胡博宏 | 15 Aug 14:40 2014
Picon

How can I load my own module when running gui_topology.py?

Hi there,

I have already written a simple TE module and it works good. Now, I want to implement an graphical interface to show real-time bandwidth and so on. I know that Ryu provides topology visualization named gui_topology.py. So I want to use it and modify it to implement the graphical interface. However, I find that I can't load my own module when gui_topology.py is running.

How can I load my own module when running gui_topology.py? Is there any guidance about it? If not, how can I implement an graphical interface to show the data which is in my module easily?

Thanks in advance!

Ivor Hu



------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
mr.dengshuoling | 15 Aug 09:12 2014
Picon

(no subject)

------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Hiroaki KAWAI | 15 Aug 03:32 2014
Picon

[PATCH] fix setup.cfg entry

SubmittingPatches.rst was renamed to CONTRIBUTING.rst.
setup.py sdist will check this dependency.
---
 setup.cfg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup.cfg b/setup.cfg
index ffc239d..6520daa 100644
--- a/setup.cfg
+++ b/setup.cfg
 <at>  <at>  -38,7 +38,7  <at>  <at>  Requires = python-eventlet, python-routes, python-webob, python-paramiko, python
 doc_files = LICENSE
             MANIFEST.in
             README.rst
-            SubmittingPatches.rst
+            CONTRIBUTING.rst
             doc/

 [global]
--

-- 
1.8.3.1

------------------------------------------------------------------------------

Gmane