New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pipelined] Add conntrack pipelined controller #2191
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
""" | ||
Copyright (c) 2016-present, Facebook, Inc. | ||
All rights reserved. | ||
|
||
This source code is licensed under the BSD-style license found in the | ||
LICENSE file in the root directory of this source tree. An additional grant | ||
of patent rights can be found in the PATENTS file in the same directory. | ||
""" | ||
|
||
from ryu.ofproto.nicira_ext import ofs_nbits | ||
from ryu.lib.packet import ether_types | ||
from ryu.ofproto.inet import IPPROTO_TCP | ||
|
||
from .base import MagmaController, ControllerType | ||
from magma.pipelined.openflow import flows | ||
from magma.pipelined.openflow.magma_match import MagmaMatch | ||
from magma.pipelined.openflow.registers import Direction | ||
|
||
|
||
class ConntrackController(MagmaController): | ||
""" | ||
A controller that sets up tunnel/ue learn flows based on uplink UE traffic | ||
to properly route downlink packets back to the UE (through the correct GRE | ||
flow tunnel). | ||
|
||
This is an optional controller and will only be used for setups with flow | ||
based GRE tunnels. | ||
|
||
conntrack flags 0 is nothing, 1 is commit | ||
|
||
CT state reference tuple (x,y): | ||
x: | ||
0: - | ||
1: + | ||
|
||
y: | ||
0x01: new | ||
0x02: est | ||
0x04: rel | ||
0x08: rpl | ||
0x10: inv | ||
0x20: trk | ||
""" | ||
|
||
APP_NAME = "conntrack" | ||
APP_TYPE = ControllerType.LOGICAL | ||
CT_NEW = 0x01 | ||
CT_EST = 0x02 | ||
CT_REL = 0x04 | ||
CT_RPL = 0x08 | ||
CT_INV = 0x10 | ||
CT_TRK = 0x20 | ||
|
||
def __init__(self, *args, **kwargs): | ||
super(ConntrackController, self).__init__(*args, **kwargs) | ||
self.tbl_num = self._service_manager.get_table_num(self.APP_NAME) | ||
self.next_table = \ | ||
self._service_manager.get_next_table_num(self.APP_NAME) | ||
self.conntrack_scratch = \ | ||
self._service_manager.allocate_scratch_tables(self.APP_NAME, 1)[0] | ||
self.connection_event_table = \ | ||
self._service_manager.INTERNAL_IPFIX_SAMPLE_TABLE_NUM | ||
self._datapath = None | ||
|
||
def initialize_on_connect(self, datapath): | ||
self._datapath = datapath | ||
self.delete_all_flows(datapath) | ||
self._install_default_flows(self._datapath) | ||
|
||
def cleanup_on_disconnect(self, datapath): | ||
""" | ||
Cleanup flows on datapath disconnect event. | ||
|
||
Args: | ||
datapath: ryu datapath struct | ||
""" | ||
self.delete_all_flows(datapath) | ||
|
||
def delete_all_flows(self, datapath): | ||
flows.delete_all_flows_from_table(datapath, self.tbl_num) | ||
flows.delete_all_flows_from_table(datapath, self.conntrack_scratch) | ||
|
||
def _install_default_flows(self, datapath): | ||
parser = datapath.ofproto_parser | ||
|
||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ct_state=(0x0, self.CT_TRK)) | ||
actions = [parser.NXActionCT( | ||
flags=0x0, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
recirc_table=self.conntrack_scratch, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_resubmit_next_service_flow(datapath, self.tbl_num, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY, | ||
resubmit_table=self.next_table) | ||
|
||
# Match all new connections | ||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ct_state=(self.CT_NEW | self.CT_TRK, | ||
self.CT_NEW | self.CT_TRK)) | ||
actions = [parser.NXActionCT( | ||
flags=0x1, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
recirc_table=self.connection_event_table, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_drop_flow(datapath, self.conntrack_scratch, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY) | ||
|
||
# Match tcp terminations (fin) | ||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ip_proto=IPPROTO_TCP, | ||
tcp_flags=(0x1,0x1), | ||
ct_state=(self.CT_EST | self.CT_TRK, | ||
self.CT_EST | self.CT_TRK)) | ||
actions = [parser.NXActionCT( | ||
flags=0x0, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
recirc_table=self.connection_event_table, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_drop_flow(datapath, self.conntrack_scratch, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY) | ||
# match tcp fin | ||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ip_proto=IPPROTO_TCP, | ||
tcp_flags=(0x1, 0x1), | ||
ct_state=(self.CT_TRK | self.CT_INV, self.CT_TRK | self.CT_INV)) | ||
# flags 0 is nothing, 1 is commit | ||
actions = [parser.NXActionCT( | ||
flags=0x0, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
recirc_table=self.connection_event_table, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_drop_flow(datapath, self.conntrack_scratch, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY) | ||
|
||
# match tcp rst | ||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ip_proto=IPPROTO_TCP, | ||
tcp_flags=(0x4, 0x4), | ||
ct_state=(self.CT_EST | self.CT_TRK, self.CT_EST | self.CT_TRK)) | ||
# flags 0 is nothing, 1 is commit | ||
actions = [parser.NXActionCT( | ||
flags=0x0, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
recirc_table=self.connection_event_table, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_drop_flow(datapath, self.conntrack_scratch, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY) | ||
|
||
inbound_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
direction=Direction.IN) | ||
outbound_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
direction=Direction.OUT) | ||
flows.add_resubmit_next_service_flow( | ||
datapath, self.tbl_num, inbound_match, [], | ||
priority=flows.MINIMUM_PRIORITY, | ||
resubmit_table=self.next_table) | ||
flows.add_resubmit_next_service_flow( | ||
datapath, self.tbl_num, outbound_match, [], | ||
priority=flows.MINIMUM_PRIORITY, | ||
resubmit_table=self.next_table) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont see need to match on direction, given that action for both flows is same. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah for some reason these are our default flows for a lot of controllers. I'm actually not sure why it was done this way initially. I've always been to lazy but I think I might finally refactor all controllers to use 1 default rule instead of 2. |
||
|
||
# TODO Currently for testing, will nuke later | ||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ct_state=(self.CT_EST | self.CT_TRK, self.CT_EST | self.CT_TRK)) | ||
# flags 0 is nothing, 1 is commit | ||
actions = [parser.NXActionCT( | ||
flags=0x0, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think it is work setting zone to avoid polluting root conntract table? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I didn't think it mattered but I can add that |
||
recirc_table=self.connection_event_table, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_drop_flow(datapath, self.conntrack_scratch, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY-5) | ||
# match tcp fin | ||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ip_proto=IPPROTO_TCP, | ||
tcp_flags=(0x1, 0x1), | ||
ct_state=(self.CT_TRK, self.CT_TRK)) | ||
# flags 0 is nothing, 1 is commit | ||
actions = [parser.NXActionCT( | ||
flags=0x0, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
recirc_table=self.connection_event_table, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_drop_flow(datapath, self.conntrack_scratch, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY-1) | ||
# match tcp fin | ||
match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, | ||
ip_proto=IPPROTO_TCP, | ||
tcp_flags=(0x1,0x1)) | ||
# flags 0 is nothing, 1 is commit | ||
actions = [parser.NXActionCT( | ||
flags=0x0, | ||
zone_src=None, | ||
zone_ofs_nbits=0, | ||
recirc_table=self.connection_event_table, | ||
alg=0, | ||
actions=[] | ||
)] | ||
flows.add_drop_flow(datapath, self.conntrack_scratch, | ||
match, actions, | ||
priority=flows.DEFAULT_PRIORITY-1) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
cookie=0x0, table=ue_mac(main_table), n_packets=20, n_bytes=2323, priority=65535,ip,nw_src=145.254.160.237 actions=load:0x7594587a06d->OXM_OF_METADATA[],load:0x1->NXM_NX_REG1[],resubmit(,conntrack(main_table)) | ||
cookie=0x0, table=ue_mac(main_table), n_packets=23, n_bytes=22768, priority=65535,ip,nw_dst=145.254.160.237 actions=load:0x7594587a06d->OXM_OF_METADATA[],load:0x10->NXM_NX_REG1[],resubmit(,conntrack(main_table)) | ||
cookie=0x0, table=conntrack(main_table), n_packets=43, n_bytes=25091, priority=10,ct_state=-trk,ip actions=ct(table=conntrack(scratch_table_0)),resubmit(,egress(main_table)),set_field:0->reg0,set_field:0->reg3 | ||
cookie=0x0, table=conntrack(main_table), n_packets=0, n_bytes=0, priority=0,ip,reg1=0x10 actions=resubmit(,egress(main_table)),set_field:0->reg0,set_field:0->reg3 | ||
cookie=0x0, table=conntrack(main_table), n_packets=0, n_bytes=0, priority=0,ip,reg1=0x1 actions=resubmit(,egress(main_table)),set_field:0->reg0,set_field:0->reg3 | ||
cookie=0x0, table=conntrack(scratch_table_0), n_packets=3, n_bytes=926, priority=10,ct_state=+new+trk,ip actions=ct(commit,table=203) | ||
cookie=0x0, table=conntrack(scratch_table_0), n_packets=2, n_bytes=108, priority=10,ct_state=+est+trk,tcp,tcp_flags=+fin actions=ct(table=203) | ||
cookie=0x0, table=conntrack(scratch_table_0), n_packets=0, n_bytes=0, priority=10,ct_state=+inv+trk,tcp,tcp_flags=+fin actions=ct(table=203) | ||
cookie=0x0, table=conntrack(scratch_table_0), n_packets=0, n_bytes=0, priority=10,ct_state=+est+trk,tcp,tcp_flags=+rst actions=ct(table=203) | ||
cookie=0x0, table=conntrack(scratch_table_0), n_packets=0, n_bytes=0, priority=9,ct_state=+trk,tcp,tcp_flags=+fin actions=ct(table=203) | ||
cookie=0x0, table=conntrack(scratch_table_0), n_packets=0, n_bytes=0, priority=9,tcp,tcp_flags=+fin actions=ct(table=203) | ||
cookie=0x0, table=conntrack(scratchreetufchdkfblrkvuitknirkrcitjhij_table_0), n_packets=38, n_bytes=24057, priority=5,ct_state=+est+trk,ip actions=ct(table=203) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you squash multiple patches in single commit, its tricky to review patch when first patch adds code and second removes it, let me know if there is way to look at final code on github.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure If i follow, when using github UI you can see the final code. https://github.com/magma/magma/pull/2191/files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I was looking at commits. I generally pull files on my laptop.