diff options
author | takahashi.minoru <takahashi.minoru7@gmail.com> | 2014-05-30 16:13:03 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-06-02 09:44:50 +0900 |
commit | 24cc165d876987701c3fd5b117cbfee84c093735 (patch) | |
tree | f0349119122671d50efe617d13bd0308c4a97ced | |
parent | 86a975aca62d9967bc2b479357c749e13f42d3c9 (diff) |
ofctl_v1_2/3: MAC arbitrary bitmask support
ofctl_rest is now enabled to use MAC arbitrary bitmask as follows:
curl -X POST -d '{"dpid": 1,
"actions":[{"port":2, "type":"OUTPUT"}],
"match":{"dl_dst":"01:02:03:ab:cd:ef/ff:ff:ff:ff:00:00"}}' http://localhost:8080/stats/flowentry/add
And now enabled to display as follows:
curl http://localhost:8080/stats/flow/1
{
"1": [
{
"actions": ["OUTPUT:2"],
"idle_timeout": 0,
"cookie": 0,
"packet_count": 0,
"hard_timeout": 0,
"byte_count": 0,
"duration_nsec": 951000000,
"priority": 0,
"duration_sec": 35,
"table_id": 0,
"match": {"dl_dst": "01:02:03:ab:00:00/ff:ff:ff:ff:00:00"}
}
]
}
Signed-off-by: TAKAHASHI Minoru <takahashi.minoru7@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/lib/ofctl_v1_2.py | 65 | ||||
-rw-r--r-- | ryu/lib/ofctl_v1_3.py | 65 |
2 files changed, 100 insertions, 30 deletions
diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py index 52fe2550..fae45ea0 100644 --- a/ryu/lib/ofctl_v1_2.py +++ b/ryu/lib/ofctl_v1_2.py @@ -194,8 +194,8 @@ def to_match(dp, attrs): convert = {'in_port': int, 'in_phy_port': int, - 'dl_src': mac.haddr_to_bin, - 'dl_dst': mac.haddr_to_bin, + 'dl_src': to_match_eth, + 'dl_dst': to_match_eth, 'dl_type': int, 'dl_vlan': int, 'vlan_pcp': int, @@ -206,8 +206,8 @@ def to_match(dp, attrs): 'nw_proto': int, 'tp_src': int, 'tp_dst': int, - 'eth_src': mac.haddr_to_bin, - 'eth_dst': mac.haddr_to_bin, + 'eth_src': to_match_eth, + 'eth_dst': to_match_eth, 'eth_type': int, 'vlan_vid': int, 'ipv4_src': to_match_ip, @@ -224,8 +224,8 @@ def to_match(dp, attrs): 'arp_op': int, 'arp_spa': to_match_ip, 'arp_tpa': to_match_ip, - 'arp_sha': mac.haddr_to_bin, - 'arp_tha': mac.haddr_to_bin, + 'arp_sha': to_match_eth, + 'arp_tha': to_match_eth, 'ipv6_src': to_match_ipv6, 'ipv6_dst': to_match_ipv6, 'ipv6_flabel': int, @@ -238,8 +238,8 @@ def to_match(dp, attrs): match_append = {'in_port': match.set_in_port, 'in_phy_port': match.set_in_phy_port, - 'dl_src': match.set_dl_src, - 'dl_dst': match.set_dl_dst, + 'dl_src': match.set_dl_src_masked, + 'dl_dst': match.set_dl_dst_masked, 'dl_type': match.set_dl_type, 'dl_vlan': match.set_vlan_vid, 'vlan_pcp': match.set_vlan_pcp, @@ -248,8 +248,8 @@ def to_match(dp, attrs): 'nw_proto': match.set_ip_proto, 'tp_src': to_match_tpsrc, 'tp_dst': to_match_tpdst, - 'eth_src': match.set_dl_src, - 'eth_dst': match.set_dl_dst, + 'eth_src': match.set_dl_src_masked, + 'eth_dst': match.set_dl_dst_masked, 'eth_type': match.set_dl_type, 'vlan_vid': match.set_vlan_vid, 'ip_dscp': match.set_ip_dscp, @@ -268,8 +268,8 @@ def to_match(dp, attrs): 'arp_op': match.set_arp_opcode, 'arp_spa': match.set_arp_spa_masked, 'arp_tpa': match.set_arp_tpa_masked, - 'arp_sha': match.set_arp_sha, - 'arp_tha': match.set_arp_tha, + 'arp_sha': match.set_arp_sha_masked, + 'arp_tha': match.set_arp_tha_masked, 'ipv6_src': match.set_ipv6_src_masked, 'ipv6_dst': match.set_ipv6_dst_masked, 'ipv6_flabel': match.set_ipv6_flabel, @@ -293,7 +293,14 @@ def to_match(dp, attrs): if key in convert: value = convert[key](value) if key in match_append: - if key == 'nw_src' or key == 'nw_dst' or \ + if key == 'dl_src' or key == 'dl_dst' or \ + key == 'eth_src' or key == 'eth_dst' or \ + key == 'arp_sha' or key == 'arp_tha': + # MAC address + eth = value[0] + mask = value[1] + match_append[key](eth, mask) + elif key == 'nw_src' or key == 'nw_dst' or \ key == 'ipv4_src' or key == 'ipv4_dst' or \ key == 'arp_spa' or key == 'arp_tpa' or \ key == 'ipv6_src' or key == 'ipv6_dst': @@ -313,6 +320,20 @@ def to_match(dp, attrs): return match +def to_match_eth(value): + eth_mask = value.split('/') + + # MAC address + eth = mac.haddr_to_bin(eth_mask[0]) + # mask + mask = mac.haddr_to_bin('ff:ff:ff:ff:ff:ff') + + if len(eth_mask) == 2: + mask = mac.haddr_to_bin(eth_mask[1]) + + return eth, mask + + def to_match_tpsrc(value, match, rest): match_append = {inet.IPPROTO_TCP: match.set_tcp_src, inet.IPPROTO_UDP: match.set_udp_src} @@ -374,6 +395,8 @@ def match_to_str(ofmatch): ofproto_v1_2.OXM_OF_IN_PHY_PORT: 'in_phy_port', ofproto_v1_2.OXM_OF_ETH_SRC: 'dl_src', ofproto_v1_2.OXM_OF_ETH_DST: 'dl_dst', + ofproto_v1_2.OXM_OF_ETH_SRC_W: 'dl_src', + ofproto_v1_2.OXM_OF_ETH_DST_W: 'dl_dst', ofproto_v1_2.OXM_OF_ETH_TYPE: 'dl_type', ofproto_v1_2.OXM_OF_VLAN_VID: 'dl_vlan', ofproto_v1_2.OXM_OF_VLAN_PCP: 'vlan_pcp', @@ -401,6 +424,8 @@ def match_to_str(ofmatch): ofproto_v1_2.OXM_OF_ARP_TPA_W: 'arp_tpa', ofproto_v1_2.OXM_OF_ARP_SHA: 'arp_sha', ofproto_v1_2.OXM_OF_ARP_THA: 'arp_tha', + ofproto_v1_2.OXM_OF_ARP_SHA_W: 'arp_sha', + ofproto_v1_2.OXM_OF_ARP_THA_W: 'arp_tha', ofproto_v1_2.OXM_OF_IPV6_SRC: 'ipv6_src', ofproto_v1_2.OXM_OF_IPV6_DST: 'ipv6_dst', ofproto_v1_2.OXM_OF_IPV6_SRC_W: 'ipv6_src', @@ -415,8 +440,9 @@ def match_to_str(ofmatch): match = {} for match_field in ofmatch.fields: key = keys[match_field.header] - if key == 'dl_src' or key == 'dl_dst': - value = mac.haddr_to_str(match_field.value) + if key == 'dl_src' or key == 'dl_dst' or \ + key == 'arp_sha' or key == 'arp_tha': + value = match_eth_to_str(match_field.value, match_field.mask) elif key == 'nw_src' or key == 'nw_dst' or \ key == 'arp_spa' or key == 'arp_tpa': value = match_ip_to_str(match_field.value, match_field.mask) @@ -429,6 +455,15 @@ def match_to_str(ofmatch): return match +def match_eth_to_str(value, mask): + eth_str = mac.haddr_to_str(value) + + if mask is not None: + eth_str = eth_str + '/' + mac.haddr_to_str(mask) + + return eth_str + + def match_ip_to_str(value, mask): ip = socket.inet_ntoa(struct.pack('!I', value)) diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py index 16b1b522..4c14e06b 100644 --- a/ryu/lib/ofctl_v1_3.py +++ b/ryu/lib/ofctl_v1_3.py @@ -210,8 +210,8 @@ def to_match(dp, attrs): match = dp.ofproto_parser.OFPMatch() convert = {'in_port': int, 'in_phy_port': int, - 'dl_src': mac.haddr_to_bin, - 'dl_dst': mac.haddr_to_bin, + 'dl_src': to_match_eth, + 'dl_dst': to_match_eth, 'dl_type': int, 'dl_vlan': int, 'vlan_pcp': int, @@ -224,8 +224,8 @@ def to_match(dp, attrs): 'tp_dst': int, 'mpls_label': int, 'metadata': to_match_metadata, - 'eth_src': mac.haddr_to_bin, - 'eth_dst': mac.haddr_to_bin, + 'eth_src': to_match_eth, + 'eth_dst': to_match_eth, 'eth_type': int, 'vlan_vid': int, 'ipv4_src': to_match_ip, @@ -242,8 +242,8 @@ def to_match(dp, attrs): 'arp_op': int, 'arp_spa': to_match_ip, 'arp_tpa': to_match_ip, - 'arp_sha': mac.haddr_to_bin, - 'arp_tha': mac.haddr_to_bin, + 'arp_sha': to_match_eth, + 'arp_tha': to_match_eth, 'ipv6_src': to_match_ipv6, 'ipv6_dst': to_match_ipv6, 'ipv6_flabel': int, @@ -259,8 +259,8 @@ def to_match(dp, attrs): 'ipv6_exthdr': int} match_append = {'in_port': match.set_in_port, - 'dl_src': match.set_dl_src, - 'dl_dst': match.set_dl_dst, + 'dl_src': match.set_dl_src_masked, + 'dl_dst': match.set_dl_dst_masked, 'dl_type': match.set_dl_type, 'dl_vlan': match.set_vlan_vid, 'vlan_pcp': match.set_vlan_pcp, @@ -271,8 +271,8 @@ def to_match(dp, attrs): 'tp_dst': to_match_tpdst, 'mpls_label': match.set_mpls_label, 'metadata': match.set_metadata_masked, - 'eth_src': match.set_dl_src, - 'eth_dst': match.set_dl_dst, + 'eth_src': match.set_dl_src_masked, + 'eth_dst': match.set_dl_dst_masked, 'eth_type': match.set_dl_type, 'vlan_vid': match.set_vlan_vid, 'ip_dscp': match.set_ip_dscp, @@ -291,8 +291,8 @@ def to_match(dp, attrs): 'arp_op': match.set_arp_opcode, 'arp_spa': match.set_arp_spa_masked, 'arp_tpa': match.set_arp_tpa_masked, - 'arp_sha': match.set_arp_sha, - 'arp_tha': match.set_arp_tha, + 'arp_sha': match.set_arp_sha_masked, + 'arp_tha': match.set_arp_tha_masked, 'ipv6_src': match.set_ipv6_src_masked, 'ipv6_dst': match.set_ipv6_dst_masked, 'ipv6_flabel': match.set_ipv6_flabel, @@ -320,7 +320,14 @@ def to_match(dp, attrs): if key in convert: value = convert[key](value) if key in match_append: - if key == 'nw_src' or key == 'nw_dst' or \ + if key == 'dl_src' or key == 'dl_dst' or \ + key == 'eth_src' or key == 'eth_dst' or \ + key == 'arp_sha' or key == 'arp_tha': + # MAC address + eth = value[0] + mask = value[1] + match_append[key](eth, mask) + elif key == 'nw_src' or key == 'nw_dst' or \ key == 'ipv4_src' or key == 'ipv4_dst' or \ key == 'arp_spa' or key == 'arp_tpa' or \ key == 'ipv6_src' or key == 'ipv6_dst': @@ -345,6 +352,20 @@ def to_match(dp, attrs): return match +def to_match_eth(value): + eth_mask = value.split('/') + + # MAC address + eth = mac.haddr_to_bin(eth_mask[0]) + # mask + mask = mac.haddr_to_bin('ff:ff:ff:ff:ff:ff') + + if len(eth_mask) == 2: + mask = mac.haddr_to_bin(eth_mask[1]) + + return eth, mask + + def to_match_tpsrc(value, match, rest): match_append = {inet.IPPROTO_TCP: match.set_tcp_src, inet.IPPROTO_UDP: match.set_udp_src} @@ -414,6 +435,8 @@ def match_to_str(ofmatch): ofproto_v1_3.OXM_OF_IN_PHY_PORT: 'in_phy_port', ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src', ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst', + ofproto_v1_3.OXM_OF_ETH_SRC_W: 'dl_src', + ofproto_v1_3.OXM_OF_ETH_DST_W: 'dl_dst', ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type', ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan', ofproto_v1_3.OXM_OF_VLAN_PCP: 'vlan_pcp', @@ -444,6 +467,8 @@ def match_to_str(ofmatch): ofproto_v1_3.OXM_OF_ARP_TPA_W: 'arp_tpa', ofproto_v1_3.OXM_OF_ARP_SHA: 'arp_sha', ofproto_v1_3.OXM_OF_ARP_THA: 'arp_tha', + ofproto_v1_3.OXM_OF_ARP_SHA_W: 'arp_sha', + ofproto_v1_3.OXM_OF_ARP_THA_W: 'arp_tha', ofproto_v1_3.OXM_OF_IPV6_SRC: 'ipv6_src', ofproto_v1_3.OXM_OF_IPV6_DST: 'ipv6_dst', ofproto_v1_3.OXM_OF_IPV6_SRC_W: 'ipv6_src', @@ -462,8 +487,9 @@ def match_to_str(ofmatch): for match_field in ofmatch.fields: key = keys[match_field.header] if key == 'dl_src' or key == 'dl_dst' or key == 'arp_sha' or \ - key == 'arp_tha' or key == 'ipv6_nd_tll' or \ - key == 'ipv6_nd_sll': + key == 'arp_tha': + value = match_eth_to_str(match_field.value, match_field.mask) + elif key == 'ipv6_nd_tll' or key == 'ipv6_nd_sll': value = mac.haddr_to_str(match_field.value) elif key == 'nw_src' or key == 'nw_dst' or \ key == 'arp_spa' or key == 'arp_tpa': @@ -480,6 +506,15 @@ def match_to_str(ofmatch): return match +def match_eth_to_str(value, mask): + eth_str = mac.haddr_to_str(value) + + if mask is not None: + eth_str = eth_str + '/' + mac.haddr_to_str(mask) + + return eth_str + + def match_ip_to_str(value, mask): ip = socket.inet_ntoa(struct.pack('!I', value)) |