def natv6_flows(self, nfvip): nat_base = nfvip.network.network_address assert nfvip.network.prefixlen == 64, 'NFVIPS IPv4 all must be /64' # pylint: disable=no-member return self.apply_actions([ # ipv6_src fc01::5 -> fc04::5:0:1, ipv6_dst fc01::1 -> fc04::1 parser.NXActionRegLoad(value=(int(nat_base) & ((2**64)-1)), dst=self.AREG, ofs_nbits=nicira_ext.ofs_nbits(0, 63)), parser.NXActionRegLoad(value=(int(nat_base) >> 64), dst=self.AREG, ofs_nbits=nicira_ext.ofs_nbits(64, 127)), ] + self.nat_actions(ether.ETH_TYPE_IPV6, nfvip, 32))
def nat_actions(self, eth_type, nfvip, nat_offset): ip_ver = nfvip.ip.version ip_src_nxm = 'ipv%u_src_nxm' % ip_ver ip_dst_nxm = 'ipv%u_dst_nxm' % ip_ver ipbits = nfvip.ip.max_prefixlen # pylint: disable=no-member return [ parser.NXActionRegMove(src_field='ipv%u_src' % ip_ver, dst_field=self.AREG, n_bits=nat_offset, src_ofs=0, dst_ofs=nat_offset), parser.NXActionRegMove(src_field='ipv%u_dst' % ip_ver, dst_field=self.AREG, n_bits=nat_offset, src_ofs=0, dst_ofs=0), # we have to load output port numbers into reg1 and reg2 because NXFlowSpecOutput() won't take a literal. parser.NXActionRegLoad(value=self.FAKEPORT, dst=self.FAKEPORTREG, ofs_nbits=nicira_ext.ofs_nbits(0, 15)), parser.NXActionRegLoad(value=self.COPROPORT, dst=self.COPROPORTREG, ofs_nbits=nicira_ext.ofs_nbits(0, 15)), # now program an inbound flow to perform NAT. parser.NXActionLearn( table_id=self.FROM_COPRO_TABLE, priority=2, hard_timeout=self.IDLE, specs=[ parser.NXFlowSpecMatch(src=eth_type, dst=('eth_type_nxm', 0), n_bits=16), parser.NXFlowSpecMatch(src=(ip_src_nxm, 0), dst=(ip_src_nxm, 0), n_bits=ipbits), parser.NXFlowSpecMatch(src=(ip_dst_nxm, 0), dst=(ip_dst_nxm, 0), n_bits=ipbits), parser.NXFlowSpecLoad(src=int(self.FAKECLIENTMAC), dst=('eth_src_nxm', 0), n_bits=48), parser.NXFlowSpecLoad(src=int(self.FAKESERVERMAC), dst=('eth_dst_nxm', 0), n_bits=48), ] + self.reg_copy(self.AREG, ip_src_nxm, ipbits) + [ parser.NXFlowSpecLoad(src=int(nfvip.ip), dst=(ip_dst_nxm, 0), n_bits=ipbits), parser.NXFlowSpecOutput(src=(self.FAKEPORTREG, 0), dst='', n_bits=16), ]), # now program outbound an outbound flow. parser.NXActionLearn( table_id=self.TO_COPRO_TABLE, priority=2, idle_timeout=self.IDLE, specs=[ parser.NXFlowSpecMatch(src=eth_type, dst=('eth_type_nxm', 0), n_bits=16), parser.NXFlowSpecMatch(src=int(nfvip.ip), dst=(ip_src_nxm, 0), n_bits=ipbits), ] + self.reg_copy(self.AREG, ip_dst_nxm, ipbits) + [ parser.NXFlowSpecLoad(src=('eth_dst_nxm', 0), dst=('eth_src_nxm', 0), n_bits=48), parser.NXFlowSpecLoad(src=('eth_src_nxm', 0), dst=('eth_dst_nxm', 0), n_bits=48), parser.NXFlowSpecLoad(src=(ip_dst_nxm, 0), dst=(ip_src_nxm, 0), n_bits=ipbits), parser.NXFlowSpecLoad(src=(ip_src_nxm, 0), dst=(ip_dst_nxm, 0), n_bits=ipbits), parser.NXFlowSpecOutput(src=(self.COPROPORTREG, 0), dst='', n_bits=16), ]), # now that future flows are programmed, handle the packet we have. parser.OFPActionSetField(eth_src=self.FAKECLIENTMAC), parser.OFPActionSetField(eth_dst=self.FAKESERVERMAC), parser.NXActionRegMove(src_field=self.AREG, dst_field=('ipv%u_src' % ip_ver), n_bits=ipbits, src_ofs=0, dst_ofs=0), parser.OFPActionSetField(**{'ipv%u_dst' % ip_ver: str(nfvip.ip)}), parser.OFPActionOutput(self.FAKEPORT) ]
def arp_reply_actions(self): # pylint: disable=no-member common_reply = self.common_reply_actions() return self.apply_actions([ parser.NXActionRegLoad(value=arp.ARP_REPLY, dst='arp_op', ofs_nbits=nicira_ext.ofs_nbits(0, 2)), parser.NXActionRegMove(src_field='arp_sha', dst_field='arp_tha', n_bits=48, src_ofs=0, dst_ofs=0), parser.NXActionRegMove(src_field='arp_tpa', dst_field=self.AREG, n_bits=32, src_ofs=0, dst_ofs=0), parser.NXActionRegMove(src_field='arp_spa', dst_field='arp_tpa', n_bits=32, src_ofs=0, dst_ofs=0), parser.NXActionRegMove(src_field=self.AREG, dst_field='arp_spa', n_bits=32, src_ofs=0, dst_ofs=0), parser.OFPActionSetField(arp_sha=FAKECLIENTMAC), ] + common_reply)
def natv4_flows(self, nfvip): nat_base = nfvip.network.network_address assert nfvip.network.prefixlen == 16, 'NFVIPS IPv4 all must be /16' # pylint: disable=no-member return self.apply_actions([ # ipv4_src 192.168.2.5->10.10.5.1, ipv4_dst 192.168.2.1->10.10.0.1 parser.NXActionRegLoad(value=int(nat_base), dst=self.AREG, ofs_nbits=nicira_ext.ofs_nbits(0, 31)), ] + self.nat_actions(ether.ETH_TYPE_IP, nfvip, 8))