Satoshi KOBAYASHI | 2 Apr 04:40 2015
Picon

Port management issue

Hi folks,

I noticed that the change of state of the ports by EventOFPPortStatus are not reflected in Datapath object. Please refer to the attachment of the script. For example, the following is the result of running the script.

----------8<----------8<----------
...(snip)...
EVENT switches->PortStatusMessageSample EventSwitchEnter
DPID: 1 Ports: [1, 2, 4294967294]
EVENT ofp_event->switches EventOFPPortStatus
EVENT ofp_event->PortStatusMessageSample EventOFPPortStatus
OFPPortStatus received: reason=DELETE desc=OFPPort(port_no=1,hw_addr='fe:73:14:ee:bf:aa',name='s1-eth1',config=0,state=0,curr=2112,advertised=0,supported=0,peer=0,curr_speed=10000000,max_speed=0)
DPID: 1 Ports: [1, 2, 4294967294]
----------8<----------8<----------

The port 1 has been deleted but do not removed from Datapath object. Is this correct behavior? We should manage the ports in user applications?

IMHO, I think that it is useful if ryu handles. Please give your opinion.

Thanks,
Satoshi

Attachment (portstatsample.py): text/x-python-script, 2176 bytes
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
YAMAMOTO Takashi | 1 Apr 06:37 2015
Picon

[PATCH 1/4] packet_data_generator2: another packet data generator using libofproto

For OpenFlow 1.5.

Signed-off-by: YAMAMOTO Takashi <yamamoto@...>
---
 ryu/tests/packet_data_generator2/Makefile |  35 ++++++++
 ryu/tests/packet_data_generator2/gen.c    | 132 ++++++++++++++++++++++++++++++
 2 files changed, 167 insertions(+)
 create mode 100644 ryu/tests/packet_data_generator2/Makefile
 create mode 100644 ryu/tests/packet_data_generator2/gen.c

diff --git a/ryu/tests/packet_data_generator2/Makefile b/ryu/tests/packet_data_generator2/Makefile
new file mode 100644
index 0000000..a6319c4
--- /dev/null
+++ b/ryu/tests/packet_data_generator2/Makefile
 <at>  <at>  -0,0 +1,35  <at>  <at> 
+# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# OVS: openvswitch installed directory  (used to look for libraries)
+# OVS_SRC: openvswitch source directory
+
+OVS?=${HOME}/ovs
+OVS_SRC?=/disks/774373a2-e180-11e3-9fa1-08606e7f74e7/git/openvswitch
+
+CPPFLAGS+=-I${OVS}/include -I${OVS_SRC}
+LDFLAGS+=-L${OVS}/lib -Wl,-R${OVS}/lib -lofproto -lopenvswitch
+
+PROG=gen
+NOMAN=
+
+all: generate
+
+generate: ${PROG}
+	${_MKMSG} "generate packet_data"
+	cd ${.CURDIR} && ${.OBJDIR}/${PROG}
+
+.include <bsd.prog.mk>
diff --git a/ryu/tests/packet_data_generator2/gen.c b/ryu/tests/packet_data_generator2/gen.c
new file mode 100644
index 0000000..ddab81e
--- /dev/null
+++ b/ryu/tests/packet_data_generator2/gen.c
 <at>  <at>  -0,0 +1,132  <at>  <at> 
+/*
+ * Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
+ * Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <lib/ofpbuf.h>
+#include <lib/ofp-actions.h>
+#include <lib/ofp-util.h>
+#include <lib/packets.h>
+
+#include <err.h>
+#include <stdio.h>
+
+void
+dump_ofpbuf(const char *name, const struct ofpbuf *buf)
+{
+    FILE *fp;
+    size_t written;
+
+    fp = fopen(name, "wb");
+    if (fp == NULL) {
+        err(1, "fopen");
+    }
+    written = fwrite(buf->data, buf->size, 1, fp);
+    if (written != 1) {
+        err(1, "fwrite");
+    }
+    if (fclose(fp) != 0) {
+        err(1, "fclose");
+    }
+}
+
+void
+fill_match(struct match *match)
+{
+    match_init_catchall(match);
+    match_set_in_port(match, 0xabcd);
+    match_set_dl_vlan(match, htons(999));
+    match_set_dl_dst(match, "\xaa\xbb\xcc\x99\x88\x77");
+    match_set_dl_type(match, htons(ETH_TYPE_IP));
+    match_set_nw_dst(match, inet_addr("192.168.2.1"));
+    match_set_tun_src(match, inet_addr("192.168.2.3"));
+    match_set_tun_dst(match, inet_addr("192.168.2.4"));
+    match_set_tun_id(match, htonll(50000));
+}
+
+struct ofpbuf *
+packet_in(enum ofputil_protocol proto)
+{
+    struct ofputil_packet_in pin;
+    struct match match;
+    struct ofpbuf *buf;
+
+    memset(&pin, 0, sizeof(pin));
+    pin.packet = "hoge";
+    pin.packet_len = 4;
+    pin.total_len = 1000;
+    pin.table_id = 100;
+    pin.buffer_id = 200;
+
+    fill_match(&match);
+    flow_get_metadata(&match.flow, &pin.fmd);
+
+    return ofputil_encode_packet_in(&pin, proto, NXPIF_OPENFLOW10);
+}
+
+struct protocol_version {
+    const char *name;
+    const char *dir_name;
+    enum ofp_version version;
+};
+
+#define P(v) {.name = "OFP" #v, .dir_name = "of" #v, \
+              .version = OFP ## v ## _VERSION,}
+
+const struct protocol_version protocols[] = {
+    P(15),
+};
+
+
+struct message {
+    const char *name;
+    struct ofpbuf *(*gen)(enum ofputil_protocol);
+};
+
+#define M(m) {.name = #m, .gen = m,}
+
+const struct message messages[] = {
+    M(packet_in),
+};
+
+#if !defined(__arraycount)
+#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
+#endif
+
+int
+main(int argc, char *argv[])
+{
+    struct ofpbuf *buf;
+    unsigned int i, j;
+
+    for (j = 0; j < __arraycount(protocols); j++) {
+        const struct protocol_version * const p = &protocols[j];
+        const enum ofputil_protocol proto =
+            ofputil_protocol_from_ofp_version(p->version);
+
+        for (i = 0; i < __arraycount(messages); i++) {
+            const struct message * const m = &messages[i];
+            char name[255];
+
+            buf = (*m->gen)(proto);
+            snprintf(name, sizeof(name),
+                "../packet_data/%s/libofproto-%s-%s.packet",
+                p->dir_name, p->name, m->name);
+            dump_ofpbuf(name, buf);
+            ofpbuf_delete(buf);
+        }
+    }
+}
--

-- 
2.1.0

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
許東豐 | 31 Mar 09:37 2015
Picon

Re: QoS Testng Problem

No problem, Mr.YAMAMOTO, but what do you mean by "restore ML cc? " Does it mean "Restore mailbox" or "Recovery mailbox?" Or CC(carbon copy) to "ryu-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org"?  

Besides, I have checked the switch-id according to your instruction. It is indeed the same as the settings in the curl commands(000000089be8d3c3). Please see the attachment. I will use the command "ovs-appctl bridge/dump-flows ovs-br0" to check the firewall function's information (the actions field) and report the result to you later today.  Thank you once again for your prompt reply and kind help!

2015-03-31 14:42 GMT+08:00 YAMAMOTO Takashi <yamamoto-jCdQPDEk3idL9jVzuh4AOg@public.gmane.org>:
btw can you restore ML cc:?  thank you.

> hi,
>
> are you sure if you are controlling the right switch?
> "ovs-vsctl get bridge ovs-br0 datapath-id" and compare it with
> the one shown in ryu console.
>
> YAMAMOTO Takashi
>
>> Dear Mr.YAMAMOTO,
>>     Thank you very much for your quick reply. VNET0 is used for vm1 and the
>> dump-flows information and the problem description is attached in this
>> mail. The other two team members in our research team have tried the
>> firewall mechanism under the same environment and it functioned normally as
>> expected. However, I am curious why QoS couldn't work even all the curl
>> settings have successfully completed.  Any further suggestions will be
>> greatly appreciated!
>>
>>
>> 2015-03-31 12:41 GMT+08:00 YAMAMOTO Takashi <yamamoto-jCdQPDEk3idL9jVzuh4AOg@public.gmane.org>:
>>
>>> hi,
>>>
>>> which vnet0 etc are used for which VMs?
>>>
>>> you can check the output of "ovs-appctl bridge/dump-flows ovs-br0"
>>> to see if expected flows are actually used.
>>> (look at n_packets/n_bytes columns)
>>>
>>> YAMAMOTO Takashi
>>>
>>> > To whom it may concern,
>>> >     My name is Jason and I am writing to asking some questions about Ryu
>>> > QoS. I have attach my problem description in the "QoS testing steps" word
>>> > file. Could you please check it out? Any suggestions or help would be
>>> > highly appreciated! Thank you!
>>> >
>>> > --
>>> > Best wishes,
>>> >
>>> > Jason Syu
>>>
>>
>>
>>
>> --
>> Best wishes,
>>
>> Jason Syu
>>
>>
>> Department of Electronic and Computer Engineering,
>> National Taiwan University of Science and Technology (NTUST)
>



--
Best wishes,

Dong-Fong Syu 
許東豐 

Department of Electronic and Computer Engineering,
National Taiwan University of Science and Technology (NTUST)
Tel :  0910137762

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Yi Tseng | 31 Mar 09:30 2015
Picon

[PATCH] simplify ofctl_rest code, add check to dpid

Avoid invalid dpid
Simplify the condition that decide which ofctl version to use
Remove unnecessary brackets

Signed-off-by: Takeshi <a86487817 <at> gmail.com>
---
 ryu/app/ofctl_rest.py          | 373 +++++++++++++++++++++++++++++------------
 ryu/lib/ofp_feature_support.py |  26 +++
 2 files changed, 295 insertions(+), 104 deletions(-)
 create mode 100644 ryu/lib/ofp_feature_support.py

diff --git a/ryu/app/ofctl_rest.py b/ryu/app/ofctl_rest.py
index c398d94..e0b1d81 100644
--- a/ryu/app/ofctl_rest.py
+++ b/ryu/app/ofctl_rest.py
<at> <at> -30,11 +30,21 <at> <at> from ryu.ofproto import ofproto_v1_3
 from ryu.lib import ofctl_v1_0
 from ryu.lib import ofctl_v1_2
 from ryu.lib import ofctl_v1_3
+from ryu.lib.ofp_feature_support import support_meter
+from ryu.lib.ofp_feature_support import support_group
+from ryu.lib.ofp_feature_support import support_experimenter
 from ryu.app.wsgi import ControllerBase, WSGIApplication
 
 
 LOG = logging.getLogger('ryu.app.ofctl_rest')
 
+# supported ofctl versions in this restful app
+supported_ofctl = {
+    ofproto_v1_0.OFP_VERSION: ofctl_v1_0,
+    ofproto_v1_2.OFP_VERSION: ofctl_v1_2,
+    ofproto_v1_3.OFP_VERSION: ofctl_v1_3,
+}
+
 # REST API
 #
 
<at> <at> -143,70 +153,92 <at> <at> class StatsController(ControllerBase):
         return (Response(content_type='application/json', body=body))
 
     def get_desc_stats(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            desc = _ofctl.get_desc_stats(dp, self.waiters)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            desc = ofctl_v1_0.get_desc_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            desc = ofctl_v1_2.get_desc_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            desc = ofctl_v1_3.get_desc_stats(dp, self.waiters)
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
 
         body = json.dumps(desc)
-        return (Response(content_type='application/json', body=body))
+        return Response(content_type='application/json', body=body)
 
     def get_flow_stats(self, req, dpid, **_kwargs):
+
         if req.body == '':
             flow = {}
+
         else:
+
             try:
                 flow = ast.literal_eval(req.body)
+
             except SyntaxError:
                 LOG.debug('invalid syntax %s', req.body)
                 return Response(status=400)
 
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            flows = ofctl_v1_0.get_flow_stats(dp, self.waiters, flow)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            flows = ofctl_v1_2.get_flow_stats(dp, self.waiters, flow)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            flows = ofctl_v1_3.get_flow_stats(dp, self.waiters, flow)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            flows = _ofctl.get_flow_stats(dp, self.waiters, flow)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
 
         body = json.dumps(flows)
-        return (Response(content_type='application/json', body=body))
+        return Response(content_type='application/json', body=body)
 
     def get_aggregate_flow_stats(self, req, dpid, **_kwargs):
+
         if req.body == '':
             flow = {}
+
         else:
             try:
                 flow = ast.literal_eval(req.body)
+
             except SyntaxError:
                 LOG.debug('invalid syntax %s', req.body)
                 return Response(status=400)
 
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            flows = ofctl_v1_0.get_aggregate_flow_stats(dp, self.waiters, flow)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            flows = ofctl_v1_2.get_aggregate_flow_stats(dp, self.waiters, flow)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            flows = ofctl_v1_3.get_aggregate_flow_stats(dp, self.waiters, flow)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            flows = _ofctl.get_aggregate_flow_stats(dp, self.waiters, flow)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -215,34 +247,46 <at> <at> class StatsController(ControllerBase):
         return Response(content_type='application/json', body=body)
 
     def get_port_stats(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            ports = ofctl_v1_0.get_port_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            ports = ofctl_v1_2.get_port_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            ports = ofctl_v1_3.get_port_stats(dp, self.waiters)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            ports = _ofctl.get_port_stats(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
 
         body = json.dumps(ports)
-        return (Response(content_type='application/json', body=body))
+        return Response(content_type='application/json', body=body)
 
     def get_queue_stats(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            queues = ofctl_v1_0.get_queue_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            queues = ofctl_v1_2.get_queue_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            queues = ofctl_v1_3.get_queue_stats(dp, self.waiters)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            queues = _ofctl.get_queue_stats(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -251,71 +295,110 <at> <at> class StatsController(ControllerBase):
         return Response(content_type='application/json', body=body)
 
     def get_meter_features(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            meters = ofctl_v1_3.get_meter_features(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
-                dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_meter(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            meters = _ofctl.get_meter_features(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
 
         body = json.dumps(meters)
-        return (Response(content_type='application/json', body=body))
+        return Response(content_type='application/json', body=body)
 
     def get_meter_config(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            meters = ofctl_v1_3.get_meter_config(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
-                dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_meter(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            meters = _ofctl.get_meter_config(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
 
         body = json.dumps(meters)
-        return (Response(content_type='application/json', body=body))
+        return Response(content_type='application/json', body=body)
 
     def get_meter_stats(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            meters = ofctl_v1_3.get_meter_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
-                dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_meter(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            meters = _ofctl.get_meter_stats(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
 
         body = json.dumps(meters)
-        return (Response(content_type='application/json', body=body))
+        return Response(content_type='application/json', body=body)
 
     def get_group_features(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            groups = ofctl_v1_2.get_group_features(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            groups = ofctl_v1_3.get_group_features(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_group(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            groups = _ofctl.get_group_features(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -324,17 +407,26 <at> <at> class StatsController(ControllerBase):
         return Response(content_type='application/json', body=body)
 
     def get_group_desc(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            groups = ofctl_v1_2.get_group_desc(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            groups = ofctl_v1_3.get_group_desc(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_group(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            groups = _ofctl.get_group_desc(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -343,17 +435,26 <at> <at> class StatsController(ControllerBase):
         return Response(content_type='application/json', body=body)
 
     def get_group_stats(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            groups = ofctl_v1_2.get_group_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            groups = ofctl_v1_3.get_group_stats(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_group(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            groups = _ofctl.get_group_stats(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -362,16 +463,22 <at> <at> class StatsController(ControllerBase):
         return Response(content_type='application/json', body=body)
 
     def get_port_desc(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            groups = ofctl_v1_0.get_port_desc(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            groups = ofctl_v1_2.get_port_desc(dp, self.waiters)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            groups = ofctl_v1_3.get_port_desc(dp, self.waiters)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            groups = _ofctl.get_port_desc(dp, self.waiters)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -380,14 +487,22 <at> <at> class StatsController(ControllerBase):
         return Response(content_type='application/json', body=body)
 
     def mod_flow_entry(self, req, cmd, **_kwargs):
+
         try:
             flow = ast.literal_eval(req.body)
+
         except SyntaxError:
             LOG.debug('invalid syntax %s', req.body)
             return Response(status=400)
 
         dpid = flow.get('dpid')
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
<at> <at> -404,12 +519,10 <at> <at> class StatsController(ControllerBase):
         else:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            ofctl_v1_0.mod_flow_entry(dp, flow, cmd)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            ofctl_v1_2.mod_flow_entry(dp, flow, cmd)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            ofctl_v1_3.mod_flow_entry(dp, flow, cmd)
+        _ofp_version = dp.ofproto.OFP_VERSION
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            _ofctl.mod_flow_entry(dp, flow, cmd)
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -417,18 +530,24 <at> <at> class StatsController(ControllerBase):
         return Response(status=200)
 
     def delete_flow_entry(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
         flow = {'table_id': dp.ofproto.OFPTT_ALL}
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            ofctl_v1_0.delete_flow_entry(dp)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            ofctl_v1_2.mod_flow_entry(dp, flow, dp.ofproto.OFPFC_DELETE)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            ofctl_v1_3.mod_flow_entry(dp, flow, dp.ofproto.OFPFC_DELETE)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            _ofctl.mod_flow_entry(dp, flow, dp.ofproto.OFPFC_DELETE)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -436,14 +555,22 <at> <at> class StatsController(ControllerBase):
         return Response(status=200)
 
     def mod_meter_entry(self, req, cmd, **_kwargs):
+
         try:
             flow = ast.literal_eval(req.body)
+
         except SyntaxError:
             LOG.debug('invalid syntax %s', req.body)
             return Response(status=400)
 
         dpid = flow.get('dpid')
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
<at> <at> -456,12 +583,16 <at> <at> class StatsController(ControllerBase):
         else:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            ofctl_v1_3.mod_meter_entry(dp, flow, cmd)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION or \
-                dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_meter(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            _ofctl.mod_meter_entry(dp, flow, cmd)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -469,21 +600,25 <at> <at> class StatsController(ControllerBase):
         return Response(status=200)
 
     def mod_group_entry(self, req, cmd, **_kwargs):
+
         try:
             group = ast.literal_eval(req.body)
+
         except SyntaxError:
             LOG.debug('invalid syntax %s', req.body)
             return Response(status=400)
 
         dpid = group.get('dpid')
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            LOG.debug('Request not supported in this OF protocol version')
-            return Response(status=501)
-
         if cmd == 'add':
             cmd = dp.ofproto.OFPGC_ADD
         elif cmd == 'modify':
<at> <at> -493,10 +628,16 <at> <at> class StatsController(ControllerBase):
         else:
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            ofctl_v1_2.mod_group_entry(dp, group, cmd)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            ofctl_v1_3.mod_group_entry(dp, group, cmd)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_group(_ofp_version):
+            LOG.debug('Request not supported in this OF protocol version')
+            return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            _ofctl.mod_group_entry(dp, group, cmd)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
<at> <at> -504,64 +645,88 <at> <at> class StatsController(ControllerBase):
         return Response(status=200)
 
     def mod_port_behavior(self, req, cmd, **_kwargs):
+
         try:
             port_config = ast.literal_eval(req.body)
+
         except SyntaxError:
             LOG.debug('invalid syntax %s', req.body)
             return Response(status=400)
 
         dpid = port_config.get('dpid')
 
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+        port_no = port_config.get('port_no', 0)
+        if not port_no.isdigit():
+            LOG.debug('invalid port_no')
+            return Response(status=400)
+
         port_no = int(port_config.get('port_no', 0))
         port_info = self.dpset.port_state[int(dpid)].get(port_no)
 
         if 'hw_addr' not in port_config:
             if port_info is not None:
                 port_config['hw_addr'] = port_info.hw_addr
+
             else:
                 return Response(status=404)
 
         if 'advertise' not in port_config:
             if port_info is not None:
                 port_config['advertise'] = port_info.advertised
+
             else:
                 return Response(status=404)
 
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
         if cmd != 'modify':
             return Response(status=404)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
-            ofctl_v1_0.mod_port_behavior(dp, port_config)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            ofctl_v1_2.mod_port_behavior(dp, port_config)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            ofctl_v1_3.mod_port_behavior(dp, port_config)
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            _ofctl.mod_port_behavior(dp, port_config)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
 
+        return Response(status=200)
+
     def send_experimenter(self, req, dpid, **_kwargs):
+
+        if not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
         dp = self.dpset.get(int(dpid))
+
         if dp is None:
             return Response(status=404)
 
         try:
             exp = ast.literal_eval(req.body)
+
         except SyntaxError:
             LOG.debug('invalid syntax %s', req.body)
             return Response(status=400)
 
-        if dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION:
-            ofctl_v1_2.send_experimenter(dp, exp)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
-            ofctl_v1_3.send_experimenter(dp, exp)
-        elif dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        if not support_experimenter(_ofp_version):
             LOG.debug('Request not supported in this OF protocol version')
             return Response(status=501)
+
+        elif _ofp_version in supported_ofctl:
+            _ofctl = supported_ofctl[_ofp_version]
+            _ofctl.send_experimenter(dp, exp)
+
         else:
             LOG.debug('Unsupported OF protocol')
             return Response(status=501)
diff --git a/ryu/lib/ofp_feature_support.py b/ryu/lib/ofp_feature_support.py
new file mode 100644
index 0000000..5200069
--- /dev/null
+++ b/ryu/lib/ofp_feature_support.py
<at> <at> -0,0 +1,26 <at> <at>
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def support_meter(version):
+    return version > 0x03
+
+
+def support_group(version):
+    return version > 0x01
+
+
+def support_experimenter(version):
+    return version > 0x01
--
1.9.5 (Apple Git-50.3)


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
MD.Badruzzaman Shakib | 30 Mar 18:10 2015

what is "Error Msg ev version OFPErrorMsg( code=8,"

When I run my application I get the following error-

error msg ev version: 0x1 msg_type 0x1 xid 0x7a93d361 OFPErrorMsg(code=8,data='\x01\r\x00\x18z\x93\xd3a\x00\x00\x03G\x00\x02\x00\x08\x00\x00\x00\x08\xff\xfb\xff\xe5\x01\x01\x00$z\x93\xd3b',type=1) type 0x1 code 0x8 0x1 0xd 0x0 0x18 0x7a 0x93 0xd3 0x61 0x0 0x0 0x3 0x47 0x0 0x2 0x0 0x8 0x0 0x0 0x0 0x8 0xff 0xfb 0xff 0xe5 0x1 0x1 0x0 0x24 0x7a 0x93 0xd3 0x62

Can anyone please tell me what is this OFPErrorMsg, code = 8 ?

Thanks
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Sandesh Shrestha | 30 Mar 07:13 2015
Picon
Picon

Measuring link bandwidth in Ryu

Hello,

I want to get the link bandwidth of the link between open vswitch and a host in Ryu App. How can I do that ?

Thanks,
Sandesh Shrestha
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
許東豐 | 30 Mar 07:04 2015
Picon

QoS Testng Problem

To whom it may concern,
    My name is Jason and I am writing to asking some questions about Ryu QoS. I have attach my problem description in the "QoS testing steps" word file. Could you please check it out? Any suggestions or help would be highly appreciated! Thank you!

--
Best wishes,

Jason Syu 
 

Attachment (QoS testing steps.docx): application/vnd.openxmlformats-officedocument.wordprocessingml.document, 9121 KiB
Attachment (testing case 2.docx): application/vnd.openxmlformats-officedocument.wordprocessingml.document, 499 KiB
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel
Yusuke Iwase | 30 Mar 04:47 2015
Picon

[PATCH 2/2] rest_firewall: Prevent adding fields which is unrelated to match

This patch prevent rest_firewall.py from adding unrelated fields
(e.g. priority, actions) into match fields.

Signed-off-by: IWASE Yusuke <iwase.yusuke0@...>
---
 ryu/app/rest_firewall.py | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/ryu/app/rest_firewall.py b/ryu/app/rest_firewall.py
index 4e52b1f..b60e62d 100644
--- a/ryu/app/rest_firewall.py
+++ b/ryu/app/rest_firewall.py
 <at>  <at>  -897,6 +897,19  <at>  <at>  class Match(object):
                  REST_NW_PROTO_ICMP: inet.IPPROTO_ICMP,
                  REST_NW_PROTO_ICMPV6: inet.IPPROTO_ICMPV6}}

+    _MATCHES = [REST_IN_PORT,
+                REST_SRC_MAC,
+                REST_DST_MAC,
+                REST_DL_TYPE,
+                REST_DL_VLAN,
+                REST_SRC_IP,
+                REST_DST_IP,
+                REST_SRC_IPV6,
+                REST_DST_IPV6,
+                REST_NW_PROTO,
+                REST_TP_SRC,
+                REST_TP_DST]
+
      <at> staticmethod
     def to_openflow(rest):

 <at>  <at>  -1002,7 +1015,7  <at>  <at>  class Match(object):
                     match.setdefault(key, Match._CONVERT[key][value])
                 else:
                     raise ValueError('Invalid rule parameter. : key=%s' % key)
-            else:
+            elif key in Match._MATCHES:
                 match.setdefault(key, value)

         return match
--

-- 
1.9.1

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
Yusuke Iwase | 30 Mar 04:45 2015
Picon

[PATCH 1/2] ofctl_v1_[23]: Ignore unkown match fields

Currently, ofctl_v1_[23].py adds non-existing match fields
when getting unknown match fields, then parser returns KeyError.
This patch fixes ofctl_v1_[23].py to ignore unkown match fields and
output error messages.

Signed-off-by: IWASE Yusuke <iwase.yusuke0@...>
---
 ryu/lib/ofctl_v1_2.py | 28 +++++++++++++++-------------
 ryu/lib/ofctl_v1_3.py | 28 +++++++++++++++-------------
 2 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py
index 1c1ff5d..37f8792 100644
--- a/ryu/lib/ofctl_v1_2.py
+++ b/ryu/lib/ofctl_v1_2.py
 <at>  <at>  -251,23 +251,25  <at>  <at>  def to_match(dp, attrs):

     kwargs = {}
     for key, value in attrs.items():
-        if key in convert:
-            value = convert[key](value)
         if key in keys:
             # For old field name
             key = keys[key]
-        if key == 'tp_src' or key == 'tp_dst':
-            # TCP/UDP port
-            conv = {inet.IPPROTO_TCP: {'tp_src': 'tcp_src',
-                                       'tp_dst': 'tcp_dst'},
-                    inet.IPPROTO_UDP: {'tp_src': 'udp_src',
-                                       'tp_dst': 'udp_dst'}}
-            ip_proto = attrs.get('nw_proto', attrs.get('ip_proto', 0))
-            key = conv[ip_proto][key]
-            kwargs[key] = value
+        if key in convert:
+            value = convert[key](value)
+            if key == 'tp_src' or key == 'tp_dst':
+                # TCP/UDP port
+                conv = {inet.IPPROTO_TCP: {'tp_src': 'tcp_src',
+                                           'tp_dst': 'tcp_dst'},
+                        inet.IPPROTO_UDP: {'tp_src': 'udp_src',
+                                           'tp_dst': 'udp_dst'}}
+                ip_proto = attrs.get('nw_proto', attrs.get('ip_proto', 0))
+                key = conv[ip_proto][key]
+                kwargs[key] = value
+            else:
+                # others
+                kwargs[key] = value
         else:
-            # others
-            kwargs[key] = value
+            LOG.error('Unknown match field: %s', key)

     return dp.ofproto_parser.OFPMatch(**kwargs)

diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py
index 04bf76d..8490206 100644
--- a/ryu/lib/ofctl_v1_3.py
+++ b/ryu/lib/ofctl_v1_3.py
 <at>  <at>  -272,23 +272,25  <at>  <at>  def to_match(dp, attrs):

     kwargs = {}
     for key, value in attrs.items():
-        if key in convert:
-            value = convert[key](value)
         if key in keys:
             # For old field name
             key = keys[key]
-        if key == 'tp_src' or key == 'tp_dst':
-            # TCP/UDP port
-            conv = {inet.IPPROTO_TCP: {'tp_src': 'tcp_src',
-                                       'tp_dst': 'tcp_dst'},
-                    inet.IPPROTO_UDP: {'tp_src': 'udp_src',
-                                       'tp_dst': 'udp_dst'}}
-            ip_proto = attrs.get('nw_proto', attrs.get('ip_proto', 0))
-            key = conv[ip_proto][key]
-            kwargs[key] = value
+        if key in convert:
+            value = convert[key](value)
+            if key == 'tp_src' or key == 'tp_dst':
+                # TCP/UDP port
+                conv = {inet.IPPROTO_TCP: {'tp_src': 'tcp_src',
+                                           'tp_dst': 'tcp_dst'},
+                        inet.IPPROTO_UDP: {'tp_src': 'udp_src',
+                                           'tp_dst': 'udp_dst'}}
+                ip_proto = attrs.get('nw_proto', attrs.get('ip_proto', 0))
+                key = conv[ip_proto][key]
+                kwargs[key] = value
+            else:
+                # others
+                kwargs[key] = value
         else:
-            # others
-            kwargs[key] = value
+            LOG.error('Unknown match field: %s', key)

     return dp.ofproto_parser.OFPMatch(**kwargs)

--

-- 
1.9.1

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
Yusuke Iwase | 30 Mar 02:07 2015
Picon

Re: Ryu rest_firewall.py

Hi,

*Please keep the mailing list.*
 Ryu-devel <ryu-devel <at> lists.sourceforge.net>

On 2015年03月27日 20:43, Ing. Susana Ballester Macías wrote:
> Ok, thanks.  Also....I'm trying to use the gui_topology app of Ryu controller so I can watch the topology of
my network in Mininet.
> 
> We ran in Mininet:
> $ sudo mn --controller remote --topo tree,depth=3
>  
> Ran the GUI application in ryu/:
> $ ./bin/ryu run --observe-links ryu/app/gui_topology/gui_topology.py

Please try the following command instead.
$ ryu-manager --observe-links ryu.app.gui_topology.gui_topology

Thanks

> 
> And we finally access to our controller IP address http://192.168.56.101:8080 with the web browser of
our VM, and it only shows "Ryu Topology Viewer" but no switches or hosts at all. 
> 
> Have you tried it?? What are we doing wrong??
> 
> 
> 
> 
> -----Mensaje original-----
> De: Yusuke Iwase [mailto:iwase.yusuke0 <at> gmail.com] 
> Enviado el: jueves, 26 de marzo de 2015 02:38 AM
> Para: sballesterm <at> electrica.cujae.edu.cu; ryu-devel <at> lists.sourceforge.net
> Asunto: Re: [Ryu-devel] Ryu rest_firewall.py
> 
> Hi,
> 
> On 2015年03月25日 18:43, sballesterm <at> electrica.cujae.edu.cu wrote:
>> Hello. I'm trying to insert a rule for denying all ICMP traffic to an specific host but I can't. So far, I've
done this:
>>
>> 1) First, I allowed in all switches all ICMP traffic and It worked just fine.
>>
>> *curl -X POST -d ’{"nw_proto":"ICMP"}’ 
>> http://localhost:8080/firewall/rules/0000000000000001*
>>
>> 2) Then, I tried to deny the ICMP traffic to a host with an IP 
>> address: 10.0.0.9
>>
>> *curl -X POST -d ’{"nw_dst": "10.0.0.9/8", "nw_proto": "ICMP", 
>> "actions": "DENY", "priority": "10"}’ 
>> http://localhost:8080/firewall/rules/0000000000000001*
>>
>> but It appears this line:*Invalid rule parameter*
>>
>> What am I doing wrong???
> 
> It seems rest_firewall.py has bugs and passes malformed match fields to ofctl_v1_*.py.
> I will make patches.
> 
> Thanks
> 
>> Untitled Document
>>
>> 50 Aniversario de la Cujae. Inaugurada por Fidel el 2 de diciembre de 
>> 1964 http://cujae.edu.cu <http://cujae.edu.cu>
>>
>>
>>
>>
>> ----------------------------------------------------------------------
>> -------- Dive into the World of Parallel Programming The Go Parallel 
>> Website, sponsored by Intel and developed in partnership with Slashdot 
>> Media, is your hub for all things parallel software development, from 
>> weekly thought leadership blogs to news, videos, case studies, 
>> tutorials and more. Take a look and join the conversation now. 
>> http://goparallel.sourceforge.net/
>>
>>
>>
>> _______________________________________________
>> Ryu-devel mailing list
>> Ryu-devel <at> lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/ryu-devel
>>
> 
> 
> 
> 50 Aniversario de la Cujae. Inaugurada por Fidel el 2 de diciembre de 1964  http://cujae.edu.cu
> 
> 

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel
MD.Badruzzaman Shakib | 29 Mar 21:52 2015

Unknown MAC address detected by ryu

Hello Ryuians,

I am trying to make an application to push shortest path flows to the switches. In my mininet topology I specifically mentioned the MAC addresses for each switch port. When I check the MAC addresses from mininet terminal it shows the MAC addresses I configured in the topology. But when I run the application, packet_in occurs from a lot of unknown MAC addresses which are not even in my topology. So its getting too difficult for me to debug the application because of these unknown MACs.

I am not actually sure from where these MACs are coming from. Can anyone help?

Also how can I push hard coded flows to the switches at the beginning of the application run(from the application not using Curl)? My intention to try this, is to avoid flooding packet when destination is unknown.

I attached the application with this email. I will be grateful if someone can help me with this.

Regards
Sakib
# This is part of our final project for the Computer Networks Graduate Course at Georgia Tech
# You can take the official course online too! Just google CS 6250 online at Georgia Tech.
#
# Contributors:
#
# Akshar Rawal (arawal <at> gatech.edu)
# Flavio Castro (castro.flaviojr <at> gmail.com)
# Logan Blyth (lblyth3 <at> gatech.edu)
# Matthew Hicks (mhicks34 <at> gatech.edu)
# Uy Nguyen (unguyen3 <at> gatech.edu)
#
# To run:
#
# ryu--manager --observe-links shortestpath.py
#
#Copyright (C) 2014, Georgia Institute of Technology.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0

#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
An OpenFlow 1.0 shortest path forwarding implementation.
"""
import logging
import struct

from ryu.base import app_manager
from ryu.controller import mac_to_port
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_0
from ryu.lib.mac import haddr_to_bin
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet

from ryu.topology.api import get_switch, get_link
from ryu.app.wsgi import ControllerBase
from ryu.topology import event, switches
import networkx as nx

class ProjectController(app_manager.RyuApp):

    OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(ProjectController, self).__init__(*args, **kwargs)
        self.mac_to_port = {}
        self.topology_api_app = self
        self.net=nx.DiGraph()								
        self.nodes = {}
        self.links = {}
        self.no_of_nodes = 0
        self.no_of_links = 0
        self.i=0
        
    
    def add_flow(self, datapath, in_port, dst, actions):
        ofproto = datapath.ofproto
        
        match = datapath.ofproto_parser.OFPMatch(
            in_port=in_port, dl_dst=haddr_to_bin(dst))
        
        mod = datapath.ofproto_parser.OFPFlowMod(
            datapath=datapath, match=match, cookie=0,
            command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
            priority=ofproto.OFP_DEFAULT_PRIORITY,
            flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
        
        datapath.send_msg(mod)

        
     <at> set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)
        
        dst = eth.dst
        src = eth.src
        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})
        # out_port = None
        if len(str(src)) > 2:
            print "######################################################################################################################"
            print "Nodes : ", self.net.nodes()
            print "Edges : ", self.net.edges()
            print "**********************************************************************************************************************"
        self.logger.info("packet in %s %s %s %s", dpid, src, dst, msg.in_port)
        # learn mac address to avoid FLOOD next time
        self.mac_to_port[dpid][src] = msg.in_port
        source_list = ["0A:00:01:01:00:00", "0A:00:02:02:00:00", "0A:00:03:03:00:00",
"0A:00:04:04:00:00", 
                       "0A:00:05:05:00:00", "0A:00:06:06:00:00", "0A:00:07:07:00:00"]
        
        if str(src) in source_list:
            #if {'port':msg.in_port} not in self.net[dpid].values():
            self.net.add_node(src)
            self.net.add_edge(dpid,src,{'port':msg.in_port})
            self.net.add_edge(src,dpid) 
            
            
        if dst in self.net.nodes():
            print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
            print "Destination is in self.net"
            #print "Source, Destination", src, dst
            #print self.net.nodes()
            path=nx.shortest_path(self.net,src,dst)
            print "path :", path 
            #print "DPID", dpid
            next=path[path.index(dpid)+1]
            print "next :", next
            print "port :", self.net[dpid][next]
            out_port=self.net[dpid][next]['port']
        else:
            out_port = ofproto.OFPP_FLOOD
            
            
        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
        
        
        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            self.add_flow(datapath, msg.in_port, dst, actions)
        
        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
            actions=actions)
        datapath.send_msg(out)

        
     <at> set_ev_cls(event.EventSwitchEnter)
    def get_topology_data(self, ev):
        switch_list = get_switch(self.topology_api_app, None)
        switches=[switch.dp.id for switch in switch_list]
        self.net.add_nodes_from(switches)
        
        
        links_list = get_link(self.topology_api_app, None)
        #print "link list",links_list
        links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
        #print links
        self.net.add_edges_from(links)
        links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list]
        #print links																			
        self.net.add_edges_from(links)
        node_num = len(self.net.nodes())
        self.i += 1
        if self.i > 5:
            for i in range(node_num):
                print str(self.net.nodes()[i])+ "'s connections :", self.net[self.net.nodes()[i]]
                
        
            
        #print "Edges to inspect port_no", self.net[]
        #print "**********List of links"
        #print self.net.nodes()
        
        #for link in links_list:
        #print link.dst
        #print link.src
        #print "Novo link"
        #self.no_of_links += 1
        
        
        #print " <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at> Printing both arrays <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at>  <at> "
    #for node in self.nodes:
        # print self.nodes[node]
        #for link in self.links:
        # print self.links[link]
        #print self.no_of_nodes
        #print self.no_of_links
        # <at> set_ev_cls(event.EventLinkAdd)
        #def get_links(self, ev):
        #print "################Something##############"
        #print ev.link.src, ev.link.dst
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@...
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Gmane