summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWAMOTO Toshihiro <iwamoto@valinux.co.jp>2016-02-01 13:12:31 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-02-01 16:38:34 +0900
commit9fe0126b930e5fe54bdc007849c2879d6db5ab86 (patch)
tree962c9079036c75d4a7d47943929effe78e9e7947
parent28cb1d59d98b067a9261296b58454da300a7854e (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.py9
-rw-r--r--ryu/ofproto/nx_actions.py111
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',