diff options
author | IWAMOTO Toshihiro <iwamoto@valinux.co.jp> | 2016-02-01 13:12:31 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-02-01 16:38:34 +0900 |
commit | 9fe0126b930e5fe54bdc007849c2879d6db5ab86 (patch) | |
tree | 962c9079036c75d4a7d47943929effe78e9e7947 | |
parent | 28cb1d59d98b067a9261296b58454da300a7854e (diff) |
Implement NXActionNAT
This action is for the conntrack Nicira extension.
Signed-off-by: IWAMOTO Toshihiro <iwamoto@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/ofproto/nicira_ext.py | 9 | ||||
-rw-r--r-- | ryu/ofproto/nx_actions.py | 111 |
2 files changed, 120 insertions, 0 deletions
diff --git a/ryu/ofproto/nicira_ext.py b/ryu/ofproto/nicira_ext.py index ef7716ba..74616b54 100644 --- a/ryu/ofproto/nicira_ext.py +++ b/ryu/ofproto/nicira_ext.py @@ -44,6 +44,7 @@ NXAST_FIN_TIMEOUT = 19 NXAST_CONTROLLER = 20 NXAST_CONJUNCTION = 34 NXAST_CT = 35 +NXAST_NAT = 36 NX_ACTION_RESUBMIT_PACK_STR = '!HHIHHB3x' NX_ACTION_RESUBMIT_SIZE = 16 @@ -241,3 +242,11 @@ NX_LEARN_DST_LOAD = 1 << 11 # Add NXAST_REG_LOAD action NX_LEARN_DST_OUTPUT = 2 << 11 # Add OFPAT_OUTPUT action. NX_LEARN_DST_RESERVED = 3 << 11 # Not yet defined. NX_LEARN_DST_MASK = 3 << 11 + +# nx_nat constants +NX_NAT_RANGE_IPV4_MIN = 1 << 0 +NX_NAT_RANGE_IPV4_MAX = 1 << 1 +NX_NAT_RANGE_IPV6_MIN = 1 << 2 +NX_NAT_RANGE_IPV6_MAX = 1 << 3 +NX_NAT_RANGE_PROTO_MIN = 1 << 4 +NX_NAT_RANGE_PROTO_MAX = 1 << 5 diff --git a/ryu/ofproto/nx_actions.py b/ryu/ofproto/nx_actions.py index f0e8db8f..f729bdf9 100644 --- a/ryu/ofproto/nx_actions.py +++ b/ryu/ofproto/nx_actions.py @@ -478,6 +478,116 @@ def generate(ofp_name, ofpp_name): msg_pack_into('!%ds' % len(data), buf, offset + payload_offset, bytes(data)) + class NXActionNAT(NXAction): + _subtype = nicira_ext.NXAST_NAT + + # pad, flags, range_present + _fmt_str = '!2xHH' + # Followed by optional parameters + + _TYPE = { + 'ascii': [ + 'range_ipv4_max', + 'range_ipv4_min', + 'range_ipv6_max', + 'range_ipv6_min', + ] + } + + def __init__(self, + flags, + range_ipv4_min='', + range_ipv4_max='', + range_ipv6_min='', + range_ipv6_max='', + range_proto_min=None, + range_proto_max=None, + type_=None, len_=None, experimenter=None, subtype=None): + super(NXActionNAT, self).__init__() + self.flags = flags + self.range_ipv4_min = range_ipv4_min + self.range_ipv4_max = range_ipv4_max + self.range_ipv6_min = range_ipv6_min + self.range_ipv6_max = range_ipv6_max + self.range_proto_min = range_proto_min + self.range_proto_max = range_proto_max + + @classmethod + def parse(cls, buf): + (flags, + range_present) = struct.unpack_from( + NXActionNAT._fmt_str, buf, 0) + rest = buf[struct.calcsize(NXActionNAT._fmt_str):] + # optional parameters + kwargs = dict() + if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MIN: + kwargs['range_ipv4_min'] = type_desc.IPv4Addr.to_user(rest[:4]) + rest = rest[4:] + if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MAX: + kwargs['range_ipv4_max'] = type_desc.IPv4Addr.to_user(rest[:4]) + rest = rest[4:] + if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MIN: + kwargs['range_ipv6_min'] = ( + type_desc.IPv6Addr.to_user(rest[:16])) + rest = rest[16:] + if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MAX: + kwargs['range_ipv6_max'] = ( + type_desc.IPv6Addr.to_user(rest[:16])) + rest = rest[16:] + if range_present & NX_NAT_RANGE_PROTO_MIN: + kwargs['range_proto_min'] = type_desc.Int2.to_user(rest[:2]) + rest = rest[2:] + if range_present & NX_NAT_RANGE_PROTO_MAX: + kwargs['range_proto_max'] = type_desc.Int2.to_user(rest[:2]) + + return cls(flags, **kwargs) + + def serialize(self, buf, offset): + # Pack optional parameters first, as range_present needs + # to be calculated. + optional_data = b'' + range_present = 0 + if self.range_ipv4_min != '': + range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MIN + optional_data += type_desc.IPv4Addr.from_user( + self.range_ipv4_min) + if self.range_ipv4_max != '': + range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MAX + optional_data += type_desc.IPv4Addr.from_user( + self.range_ipv4_max) + if self.range_ipv6_min != '': + range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MIN + optional_data += type_desc.IPv6Addr.from_user( + self.range_ipv6_min) + if self.range_ipv6_max != '': + range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MAX + optional_data += type_desc.IPv6Addr.from_user( + self.range_ipv6_max) + if self.range_proto_min is not None: + range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MIN + optional_data += type_desc.Int2.from_user( + self.range_proto_min) + if self.range_proto_max is not None: + range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MAX + optional_data += type_desc.Int2.from_user( + self.range_proto_max) + + data = bytearray() + msg_pack_into(NXActionNAT._fmt_str, data, 0, + self.flags, + range_present) + msg_pack_into('!%ds' % len(optional_data), data, len(data), + optional_data) + + payload_offset = ( + ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE + + struct.calcsize(NXAction._fmt_str) + ) + self.len = utils.round_up(payload_offset + len(data), 8) + super(NXActionNAT, self).serialize(buf, offset) + msg_pack_into('!%ds' % len(data), buf, offset + payload_offset, + bytes(data)) + def add_attr(k, v): v.__module__ = ofpp.__name__ # Necessary for stringify stuff setattr(ofpp, k, v) @@ -491,6 +601,7 @@ def generate(ofp_name, ofpp_name): 'NXActionConjunction', 'NXActionResubmitTable', 'NXActionCT', + 'NXActionNAT', '_NXFlowSpec', # exported for testing 'NXFlowSpecMatch', 'NXFlowSpecLoad', |