Skip to content
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

[acl-loader]: Add support for handling control plane ACLs #172

Merged
merged 4 commits into from
Dec 20, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions acl_loader/main.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@

#!/usr/bin/env python

import click
import sys
import os.path
import json
import argparse
import tabulate
from natsort import natsorted

Expand Down Expand Up @@ -44,6 +40,8 @@ class AclLoader(object):

ACL_TABLE = "ACL_TABLE"
ACL_RULE = "ACL_RULE"
ACL_TABLE_TYPE_MIRROR = "MIRROR"
ACL_TABLE_TYPE_CTRLPLANE = "CTRLPLANE"
MIRROR_SESSION = "MIRROR_SESSION"
SESSION_PREFIX = "everflow"

Expand Down Expand Up @@ -157,11 +155,19 @@ def is_table_valid(self, tname):

def is_table_mirror(self, tname):
"""
Check if ACL table type is MIRROR
Check if ACL table type is ACL_TABLE_TYPE_MIRROR
:param tname: ACL table name
:return: True if table type is MIRROR else False
:return: True if table type is ACL_TABLE_TYPE_MIRROR else False
"""
return self.tables_db_info[tname]['type'].upper() == "MIRROR"
return self.tables_db_info[tname]['type'].upper() == self.ACL_TABLE_TYPE_MIRROR

def is_table_control_plane(self, tname):
"""
Check if ACL table type is ACL_TABLE_TYPE_CTRLPLANE
:param tname: ACL table name
:return: True if table type is ACL_TABLE_TYPE_CTRLPLANE else False
"""
return self.tables_db_info[tname]['type'].upper() == self.ACL_TABLE_TYPE_CTRLPLANE

def load_rules_from_file(self, filename):
"""
Expand All @@ -177,7 +183,9 @@ def convert_action(self, table_name, rule_idx, rule):
rule_props = {}

if rule.actions.config.forwarding_action == "ACCEPT":
if self.is_table_mirror(table_name):
if self.is_table_control_plane(table_name):
rule_props["PACKET_ACTION"] = "ACCEPT"
elif self.is_table_mirror(table_name):
session_name = self.get_session_name()
if not session_name:
raise AclLoaderException("Mirroring session does not exist")
Expand Down Expand Up @@ -239,6 +247,15 @@ def convert_ipv4(self, table_name, rule_idx, rule):
return rule_props

def convert_port(self, port):
"""
Convert port field format from openconfig ACL to Config DB schema
:param port: String, ACL port number or range in openconfig format
:return: Tuple, first value is converted port string,
second value is boolean, True if value is a port range, False
if it is a single port value
"""
# OpenConfig port range is of the format "####..####", whereas
# Config DB format is "####-####"
if ".." in port:
return port.replace("..", "-"), True
else:
Expand All @@ -258,21 +275,21 @@ def convert_transport(self, table_name, rule_idx, rule):

for flag in rule.transport.config.tcp_flags:
if flag == "TCP_FIN":
tcp_flags = tcp_flags | 0x01
tcp_flags |= 0x01
if flag == "TCP_SYN":
tcp_flags = tcp_flags | 0x02
tcp_flags |= 0x02
if flag == "TCP_RST":
tcp_flags = tcp_flags | 0x04
tcp_flags |= 0x04
if flag == "TCP_PSH":
tcp_flags = tcp_flags | 0x08
tcp_flags |= 0x08
if flag == "TCP_ACK":
tcp_flags = tcp_flags | 0x10
tcp_flags |= 0x10
if flag == "TCP_URG":
tcp_flags = tcp_flags | 0x20
tcp_flags |= 0x20
if flag == "TCP_ECE":
tcp_flags = tcp_flags | 0x40
tcp_flags |= 0x40
if flag == "TCP_CWR":
tcp_flags = tcp_flags | 0x80
tcp_flags |= 0x80

if tcp_flags:
rule_props["TCP_FLAGS"] = '0x{:02x}/0x{:02x}'.format(tcp_flags, tcp_flags)
Expand Down Expand Up @@ -308,7 +325,7 @@ def deny_rule(self, table_name):
rule_props = {}
rule_data = {(table_name, "DEFAULT_RULE"): rule_props}
rule_props["PRIORITY"] = self.min_priority
rule_props["ETHER_TYPE"] = "0x0800"
rule_props["ETHER_TYPE"] = self.ethertype_map["ETHERTYPE_IPV4"]
rule_props["PACKET_ACTION"] = "DROP"
return rule_data

Expand Down Expand Up @@ -420,7 +437,7 @@ def show_rule(self, table_name, rule_id):
:param rule_id: Optional. ACL rule name. Filter rule by specified rule name.
:return:
"""
header = ("Rule ID", "Table Name", "Priority", "Action", "Match")
header = ("Rule ID", "Rule Name", "Priority", "Action", "Match")

ignore_list = ["PRIORITY", "PACKET_ACTION", "MIRROR_ACTION"]

Expand Down