mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-08 13:56:09 +02:00
ofctl_v1_2/3: IP arbitrary bitmask support
Openflow 1.1 and later versions allow the use of IP address with arbitrary bitmask in match fields. This adds arbitrary bitmask support to related functions. After applying this patch, it's no longer compatible with ACL hybrid CIDR format (Cisco-like ACL bitmasks) because such format exists only in some router's ACL configuration. Reported-by: Yi-Ching Lee <potatoching11@gmail.com> Reported-by: Li-Der Chou <cld@csie.ncu.edu.tw> Signed-off-by: Wei-Li Tang <alextwl@xinguard.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
8728c11e12
commit
97f81e58a2
@ -326,13 +326,37 @@ def to_match_tpdst(value, match, rest):
|
||||
|
||||
|
||||
def to_match_ip(value):
|
||||
ip = netaddr.IPNetwork(value)
|
||||
return ip.ip.value, ip.netmask.value
|
||||
ip_mask = value.split('/')
|
||||
|
||||
# IP address
|
||||
ipv4 = struct.unpack('!I', socket.inet_aton(ip_mask[0]))[0]
|
||||
# netmask
|
||||
netmask = ofproto_v1_2_parser.UINT32_MAX
|
||||
|
||||
if len(ip_mask) == 2:
|
||||
# Check the mask is CIDR or not.
|
||||
if ip_mask[1].isdigit():
|
||||
netmask &= ofproto_v1_2_parser.UINT32_MAX << 32 - int(ip_mask[1])
|
||||
else:
|
||||
netmask = struct.unpack('!I', socket.inet_aton(ip_mask[1]))[0]
|
||||
|
||||
return ipv4, netmask
|
||||
|
||||
|
||||
def to_match_ipv6(value):
|
||||
ip = netaddr.IPNetwork(value)
|
||||
return ip.ip.words, ip.netmask.words
|
||||
ip_mask = value.split('/')
|
||||
|
||||
if len(ip_mask) == 2 and ip_mask[1].isdigit() is False:
|
||||
# Both address and netmask are colon-hexadecimal.
|
||||
ipv6 = netaddr.IPAddress(ip_mask[0]).words
|
||||
netmask = netaddr.IPAddress(ip_mask[1]).words
|
||||
else:
|
||||
# For other formats.
|
||||
network = netaddr.IPNetwork(value)
|
||||
ipv6 = network.ip.words
|
||||
netmask = network.netmask.words
|
||||
|
||||
return ipv6, netmask
|
||||
|
||||
|
||||
def match_to_str(ofmatch):
|
||||
|
||||
@ -368,13 +368,37 @@ def to_match_tpdst(value, match, rest):
|
||||
|
||||
|
||||
def to_match_ip(value):
|
||||
ip = netaddr.IPNetwork(value)
|
||||
return ip.ip.value, ip.netmask.value
|
||||
ip_mask = value.split('/')
|
||||
|
||||
# IP address
|
||||
ipv4 = struct.unpack('!I', socket.inet_aton(ip_mask[0]))[0]
|
||||
# netmask
|
||||
netmask = ofproto_v1_3_parser.UINT32_MAX
|
||||
|
||||
if len(ip_mask) == 2:
|
||||
# Check the mask is CIDR or not.
|
||||
if ip_mask[1].isdigit():
|
||||
netmask &= ofproto_v1_3_parser.UINT32_MAX << 32 - int(ip_mask[1])
|
||||
else:
|
||||
netmask = struct.unpack('!I', socket.inet_aton(ip_mask[1]))[0]
|
||||
|
||||
return ipv4, netmask
|
||||
|
||||
|
||||
def to_match_ipv6(value):
|
||||
ip = netaddr.IPNetwork(value)
|
||||
return ip.ip.words, ip.netmask.words
|
||||
ip_mask = value.split('/')
|
||||
|
||||
if len(ip_mask) == 2 and ip_mask[1].isdigit() is False:
|
||||
# Both address and netmask are colon-hexadecimal.
|
||||
ipv6 = netaddr.IPAddress(ip_mask[0]).words
|
||||
netmask = netaddr.IPAddress(ip_mask[1]).words
|
||||
else:
|
||||
# For other formats.
|
||||
network = netaddr.IPNetwork(value)
|
||||
ipv6 = network.ip.words
|
||||
netmask = network.netmask.words
|
||||
|
||||
return ipv6, netmask
|
||||
|
||||
|
||||
def to_match_metadata(value):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user