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>
This commit is contained in:
parent
28cb1d59d9
commit
9fe0126b93
@ -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
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user