c8b45e18b0
Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Reviewed-by: Simon Horman <horms@verge.net.au> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
462 lines
15 KiB
Python
462 lines
15 KiB
Python
# 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.
|
|
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
import logging
|
|
|
|
from ryu.ofproto import ofproto_v1_2
|
|
from ryu.ofproto import ether
|
|
from ryu.ofproto import inet
|
|
from ryu.tests.integrated import tester
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class RunTest(tester.TestFlowBase):
|
|
""" Test case for add flows of Actions
|
|
"""
|
|
OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(RunTest, self).__init__(*args, **kwargs)
|
|
|
|
self._verify = []
|
|
|
|
def add_apply_actions(self, dp, actions, match=None):
|
|
inst = [dp.ofproto_parser.OFPInstructionActions(
|
|
dp.ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
|
if match is None:
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
m = dp.ofproto_parser.OFPFlowMod(dp, 0, 0, 0,
|
|
dp.ofproto.OFPFC_ADD,
|
|
0, 0, 0xff, 0xffffffff,
|
|
dp.ofproto.OFPP_ANY,
|
|
dp.ofproto.OFPG_ANY,
|
|
0, match, inst)
|
|
dp.send_msg(m)
|
|
|
|
def add_set_field_action(self, dp, field, value, match=None):
|
|
self._verify = [dp.ofproto.OFPAT_SET_FIELD,
|
|
'field', field, value]
|
|
f = dp.ofproto_parser.OFPMatchField.make(field, value)
|
|
actions = [dp.ofproto_parser.OFPActionSetField(f), ]
|
|
self.add_apply_actions(dp, actions, match=match)
|
|
|
|
def verify_default(self, dp, stats):
|
|
verify = self._verify
|
|
self._verify = []
|
|
|
|
type_ = name = field = value = None
|
|
if len(verify) == 1:
|
|
(type_, ) = verify
|
|
elif len(verify) == 3:
|
|
(type_, name, value) = verify
|
|
elif len(verify) == 4:
|
|
(type_, name, field, value) = verify
|
|
else:
|
|
return "self._verify is invalid."
|
|
|
|
try:
|
|
action = stats[0].instructions[0].actions[0]
|
|
if action.cls_action_type != type_:
|
|
return "Action type error. send:%s, val:%s" \
|
|
% (type_, action.cls_action_type)
|
|
except IndexError:
|
|
return "Action is not setting."
|
|
|
|
s_val = None
|
|
if name:
|
|
try:
|
|
s_val = getattr(action, name)
|
|
except AttributeError:
|
|
pass
|
|
|
|
if name == 'field':
|
|
if s_val.header != field:
|
|
return "Field error. send:%s val:%s" \
|
|
% (field, s_val.header)
|
|
s_val = s_val.value
|
|
|
|
if name and s_val != value:
|
|
return "Value error. send:%s=%s val:%s" \
|
|
% (name, value, s_val)
|
|
|
|
return True
|
|
|
|
def verify_action_drop(self, dp, stats):
|
|
for s in stats:
|
|
for i in s.instructions:
|
|
if len(i.actions):
|
|
return "has actions. %s" % (i.actions)
|
|
return True
|
|
|
|
# Test of General Actions
|
|
def test_action_output(self, dp):
|
|
out_port = 255
|
|
self._verify = [dp.ofproto.OFPAT_OUTPUT,
|
|
'port', out_port]
|
|
|
|
actions = [dp.ofproto_parser.OFPActionOutput(out_port, 0), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_drop(self, dp):
|
|
self.add_apply_actions(dp, [])
|
|
|
|
# Test of Push-Tag/Pop-Tag Actions
|
|
def test_action_push_vlan(self, dp):
|
|
ethertype = ether.ETH_TYPE_8021Q
|
|
self._verify = [dp.ofproto.OFPAT_PUSH_VLAN,
|
|
'ethertype', ethertype]
|
|
|
|
actions = [dp.ofproto_parser.OFPActionPushVlan(ethertype)]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_pop_vlan(self, dp):
|
|
self._verify = [dp.ofproto.OFPAT_POP_VLAN, ]
|
|
|
|
actions = [dp.ofproto_parser.OFPActionPopVlan(), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_push_mpls(self, dp):
|
|
ethertype = ether.ETH_TYPE_MPLS
|
|
self._verify = [dp.ofproto.OFPAT_PUSH_MPLS,
|
|
'ethertype', ethertype]
|
|
|
|
actions = [dp.ofproto_parser.OFPActionPushMpls(ethertype), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_pop_mpls(self, dp):
|
|
ethertype = ether.ETH_TYPE_8021Q
|
|
self._verify = [dp.ofproto.OFPAT_POP_MPLS,
|
|
'ethertype', ethertype]
|
|
actions = [dp.ofproto_parser.OFPActionPopMpls(ethertype), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
# Test of Set-Filed Actions
|
|
def test_action_set_field_dl_dst(self, dp):
|
|
field = dp.ofproto.OXM_OF_ETH_DST
|
|
dl_dst = 'e2:7a:09:79:0b:0f'
|
|
value = self.haddr_to_bin(dl_dst)
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_dl_src(self, dp):
|
|
field = dp.ofproto.OXM_OF_ETH_SRC
|
|
dl_src = '08:82:63:b6:62:05'
|
|
value = self.haddr_to_bin(dl_src)
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_dl_type(self, dp):
|
|
field = dp.ofproto.OXM_OF_ETH_TYPE
|
|
value = ether.ETH_TYPE_IPV6
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_vlan_vid(self, dp):
|
|
field = dp.ofproto.OXM_OF_VLAN_VID
|
|
value = 0x1e4
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_vlan_pcp(self, dp):
|
|
field = dp.ofproto.OXM_OF_VLAN_PCP
|
|
value = 3
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_vlan_vid(1)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_nw_dscp(self, dp):
|
|
field = dp.ofproto.OXM_OF_IP_DSCP
|
|
value = 32
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_nw_ecn(self, dp):
|
|
field = dp.ofproto.OXM_OF_IP_ECN
|
|
value = 1
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_ip_proto(self, dp):
|
|
field = dp.ofproto.OXM_OF_IP_PROTO
|
|
value = inet.IPPROTO_TCP
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_ipv4_src(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV4_SRC
|
|
ipv4_src = '192.168.3.92'
|
|
value = self.ipv4_to_int(ipv4_src)
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_ipv4_dst(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV4_DST
|
|
ipv4_dst = '192.168.74.122'
|
|
value = self.ipv4_to_int(ipv4_dst)
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_tcp_src(self, dp):
|
|
field = dp.ofproto.OXM_OF_TCP_SRC
|
|
value = 105
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
match.set_ip_proto(inet.IPPROTO_TCP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_tcp_dst(self, dp):
|
|
field = dp.ofproto.OXM_OF_TCP_DST
|
|
value = 75
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
match.set_ip_proto(inet.IPPROTO_TCP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_udp_src(self, dp):
|
|
field = dp.ofproto.OXM_OF_UDP_SRC
|
|
value = 197
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
match.set_ip_proto(inet.IPPROTO_UDP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_udp_dst(self, dp):
|
|
field = dp.ofproto.OXM_OF_UDP_DST
|
|
value = 17
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_IP)
|
|
match.set_ip_proto(inet.IPPROTO_UDP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_icmpv4_type(self, dp):
|
|
field = dp.ofproto.OXM_OF_ICMPV4_TYPE
|
|
value = 8
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_ip_proto(inet.IPPROTO_ICMP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_icmpv4_code(self, dp):
|
|
field = dp.ofproto.OXM_OF_ICMPV4_CODE
|
|
value = 2
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_ip_proto(inet.IPPROTO_ICMP)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_arp_op(self, dp):
|
|
field = dp.ofproto.OXM_OF_ARP_OP
|
|
value = 2
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_ARP)
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_arp_spa(self, dp):
|
|
field = dp.ofproto.OXM_OF_ARP_SPA
|
|
nw_src = '192.168.132.179'
|
|
value = self.ipv4_to_int(nw_src)
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_ARP)
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_arp_tpa(self, dp):
|
|
field = dp.ofproto.OXM_OF_ARP_TPA
|
|
nw_dst = '192.168.118.85'
|
|
value = self.ipv4_to_int(nw_dst)
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_ARP)
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_arp_sha(self, dp):
|
|
field = dp.ofproto.OXM_OF_ARP_SHA
|
|
arp_sha = '50:29:e7:7f:6c:7f'
|
|
value = self.haddr_to_bin(arp_sha)
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_ARP)
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_arp_tha(self, dp):
|
|
field = dp.ofproto.OXM_OF_ARP_THA
|
|
arp_tha = '71:c8:72:2f:47:fd'
|
|
value = self.haddr_to_bin(arp_tha)
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_ARP)
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_ipv6_src(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV6_SRC
|
|
ipv6_src = '7527:c798:c772:4a18:117a:14ff:c1b6:e4ef'
|
|
value = self.ipv6_to_int(ipv6_src)
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_ipv6_dst(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV6_DST
|
|
ipv6_dst = '8893:65b3:6b49:3bdb:3d2:9401:866c:c96'
|
|
value = self.ipv6_to_int(ipv6_dst)
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_ipv6_flabel(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV6_FLABEL
|
|
value = 0x2c12
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_icmpv6_type(self, dp):
|
|
field = dp.ofproto.OXM_OF_ICMPV6_TYPE
|
|
value = 129
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_icmpv6_code(self, dp):
|
|
field = dp.ofproto.OXM_OF_ICMPV6_CODE
|
|
value = 2
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_ipv6_nd_target(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV6_ND_TARGET
|
|
target = "5420:db3f:921b:3e33:2791:98f:dd7f:2e19"
|
|
value = self.ipv6_to_int(target)
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_ipv6_nd_sll(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV6_ND_SLL
|
|
sll = "54:db:3f:3e:27:19"
|
|
value = self.haddr_to_bin(sll)
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_ipv6_nd_tll(self, dp):
|
|
field = dp.ofproto.OXM_OF_IPV6_ND_TLL
|
|
tll = "83:13:48:1e:d0:b0"
|
|
value = self.haddr_to_bin(tll)
|
|
|
|
self.add_set_field_action(dp, field, value)
|
|
|
|
def test_action_set_field_mpls_label(self, dp):
|
|
field = dp.ofproto.OXM_OF_MPLS_LABEL
|
|
value = 0x4c
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_MPLS)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
def test_action_set_field_mpls_tc(self, dp):
|
|
field = dp.ofproto.OXM_OF_MPLS_TC
|
|
value = 0b101
|
|
|
|
match = dp.ofproto_parser.OFPMatch()
|
|
match.set_dl_type(ether.ETH_TYPE_MPLS)
|
|
|
|
self.add_set_field_action(dp, field, value, match)
|
|
|
|
# Test of Change-TTL Actions
|
|
def test_action_set_mpls_ttl(self, dp):
|
|
mpls_ttl = 8
|
|
self._verify = [dp.ofproto.OFPAT_SET_MPLS_TTL,
|
|
'mpls_ttl', mpls_ttl]
|
|
actions = [dp.ofproto_parser.OFPActionSetMplsTtl(mpls_ttl), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_dec_mpls_ttl(self, dp):
|
|
self._verify = [dp.ofproto.OFPAT_DEC_MPLS_TTL]
|
|
actions = [dp.ofproto_parser.OFPActionDecMplsTtl(), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_set_nw_ttl(self, dp):
|
|
nw_ttl = 64
|
|
self._verify = [dp.ofproto.OFPAT_SET_NW_TTL,
|
|
'nw_ttl', nw_ttl]
|
|
actions = [dp.ofproto_parser.OFPActionSetNwTtl(nw_ttl), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_dec_nw_ttl(self, dp):
|
|
self._verify = [dp.ofproto.OFPAT_DEC_NW_TTL]
|
|
actions = [dp.ofproto_parser.OFPActionDecNwTtl(), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_copy_ttl_out(self, dp):
|
|
self._verify = [dp.ofproto.OFPAT_COPY_TTL_OUT]
|
|
actions = [dp.ofproto_parser.OFPActionCopyTtlOut(), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def test_action_copy_ttl_in(self, dp):
|
|
self._verify = [dp.ofproto.OFPAT_COPY_TTL_IN]
|
|
actions = [dp.ofproto_parser.OFPActionCopyTtlIn(), ]
|
|
self.add_apply_actions(dp, actions)
|
|
|
|
def is_supported(self, t):
|
|
# Open vSwitch 1.10 does not support MPLS yet.
|
|
unsupported = [
|
|
'test_action_set_field_ip_proto',
|
|
'test_action_set_field_dl_type',
|
|
'test_action_set_field_arp',
|
|
'test_action_set_field_ipv6',
|
|
'test_action_set_field_icmp',
|
|
'test_action_set_nw_ttl',
|
|
'test_action_copy_ttl_in',
|
|
'test_action_copy_ttl_out',
|
|
'test_action_dec_mpls_ttl',
|
|
'test_action_pop_mpls',
|
|
'test_action_push_mpls',
|
|
'test_action_set_field_mpls_label',
|
|
'test_action_set_field_mpls_tc',
|
|
'test_action_set_mpls_ttl'
|
|
]
|
|
for u in unsupported:
|
|
if t.find(u) != -1:
|
|
return False
|
|
|
|
return True
|