-
Notifications
You must be signed in to change notification settings - Fork 1k
ACL and Decap permanent configuration #132
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
Changes from all commits
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,167 @@ | ||
| #!/usr/bin/python | ||
|
|
||
| import calendar | ||
| import os | ||
| import sys | ||
| import socket | ||
| import struct | ||
| import json | ||
| import copy | ||
| import ipaddr as ipaddress | ||
| from collections import defaultdict | ||
|
|
||
| from lxml import etree as ET | ||
| from lxml.etree import QName | ||
|
|
||
| def dump_json(filename, data): | ||
| with open(filename, 'w') as outfile: | ||
| json.dump(data, outfile, indent=4, sort_keys=True, separators=(',', ':')) | ||
|
|
||
| # Return: res, value, n (num of consumed elements) | ||
| def is_port(props, idx): | ||
| if idx >= len(props): | ||
| return False, "", 0 | ||
| if props[idx] == "eq": | ||
| return True, props[idx+1], 2 | ||
| if props[idx] == "gt": | ||
| return True, props[idx+1]+"-65535", 2 | ||
| if props[idx] == "lt": | ||
| return True, "1-"+props[idx+1], 2 | ||
| if props[idx] == "range": | ||
| return True, props[idx+1]+"-"+props[idx+2], 3 | ||
| return False, "", 0 | ||
|
|
||
| def is_subnet(props, idx): | ||
| if idx >= len(props): | ||
| return False, "", 0 | ||
| if props[idx] == "any": | ||
| return True, "" | ||
| try: | ||
| socket.inet_aton(props[idx].split("/")[0]) | ||
| return True, props[idx] | ||
| except socket.error: | ||
| False, "" | ||
|
|
||
| def generate_rule_json(table_name, rule_idx, rule): | ||
| rule_props_list = rule.text.split() | ||
| rule_props = {} | ||
| rule_data = {} | ||
| rule_data["ACL_RULE_TABLE:"+table_name+":Rule_"+str(rule_idx)] = rule_props | ||
| rule_data["OP"] = "SET" | ||
| rule_props["priority"] = "10" | ||
| if rule_props_list[0] == "permit": | ||
| rule_props["PACKET_ACTION"] = "FORWARD" | ||
| elif rule_props_list[0] == "deny": | ||
| rule_props["PACKET_ACTION"] = "DROP" | ||
| else: | ||
| print "Unknown rule action %s in table %s, rule %d!" % (rule_props_list[0], table_name, rule_idx) | ||
|
|
||
| if rule_props_list[1] == "ip": | ||
| rule_props["IP_TYPE"] = "IPV4ANY" | ||
| elif rule_props_list[1] == "tcp": | ||
| rule_props["IP_PROTOCOL"] = "6" # TCP protocol | ||
| elif rule_props_list[1] == "icmp": | ||
| rule_props["IP_PROTOCOL"] = "1" # ICMP protocol | ||
| elif rule_props_list[1] == "udp": | ||
| rule_props["IP_PROTOCOL"] = "17" # UDP protocol | ||
| else: | ||
| try: | ||
| int(rule_props_list[1]) | ||
| except: | ||
| print "Unknown rule protocol %s in table %s, rule %d!" % (rule_props_list[1], table_name, rule_idx) | ||
| return {} | ||
| else: | ||
| rule_props["IP_PROTOCOL"] = rule_props_list[1] | ||
|
|
||
|
|
||
| res, val = is_subnet(rule_props_list, 2) | ||
| if not res: | ||
| print "Src subnet error\n" | ||
| return {} | ||
| elif val: | ||
| rule_props["SRC_IP"] = val | ||
|
|
||
| i = 3 | ||
| res, val, n = is_port(rule_props_list, i) | ||
| if res: | ||
| if val.find("-") < 0: | ||
| rule_props["L4_SRC_PORT"] = val | ||
| else: | ||
| rule_props["L4_SRC_PORT_RANGE"] = val | ||
|
|
||
| i+=n | ||
|
|
||
|
|
||
| res, val = is_subnet(rule_props_list, i) | ||
| if not res: | ||
| print "Dst subnet error" | ||
| return {} | ||
| elif val: | ||
| rule_props["DST_IP"] = val | ||
| i+=1 | ||
|
|
||
| res, val, n = is_port(rule_props_list, i) | ||
| if res: | ||
| if val.find("-") < 0: | ||
| rule_props["L4_DST_PORT"] = val | ||
| else: | ||
| rule_props["L4_DST_PORT_RANGE"] = val | ||
| i+=n | ||
|
|
||
| if i < len(rule_props_list): | ||
| if rule_props_list[i] == "rst": | ||
| rule_props["TCP_FLAGS"] = "0xFF/0x04" | ||
| if rule_props_list[i] == "ack": | ||
| rule_props["TCP_FLAGS"] = "0xFF/0x10" | ||
| if rule_props_list[i] == "syn": | ||
| rule_props["TCP_FLAGS"] = "0xFF/0x02" | ||
|
|
||
| return rule_data | ||
|
|
||
|
|
||
| def generate_table_json(policies): | ||
| table_name = "" | ||
| #print policy.attrib | ||
| table_name = "ACL_Table" | ||
|
|
||
| table_props = {} | ||
| table_props["policy_desc"] = table_name | ||
| table_props["type"] = "L3" | ||
| table_props["ports"] = ",".join("Ethernet%d" % x for x in range(0, 128, 4)) | ||
|
|
||
| table_data = [{}] | ||
| table_data[0]["ACL_TABLE:"+table_name] = table_props | ||
| table_data[0]["OP"] = "SET" | ||
| dump_json("table_"+table_name+".json", table_data) | ||
|
|
||
| rule_idx = 0 | ||
| rule_data = [] | ||
| for policy in policies: | ||
| for rule in policy.findall("Rule"): | ||
| rule_props = generate_rule_json(table_name, rule_idx, rule) | ||
| if rule_props: | ||
| rule_data.append(rule_props) | ||
| rule_idx+=1 | ||
|
|
||
| dump_json("rules_for_"+table_name+".json", rule_data) | ||
|
|
||
| def xml_to_json(filename): | ||
| root = ET.parse(filename).getroot() | ||
|
|
||
| for acl in root.findall("AccessControlList"): | ||
| for aclgr in acl.findall("AclGroup"): | ||
| generate_table_json(aclgr.findall("Policy")) | ||
|
|
||
| return | ||
|
|
||
|
|
||
| def main(): | ||
| xml_to_json(sys.argv[1]) | ||
|
|
||
| def debug_main(): | ||
| print_parse_xml('switch1') | ||
|
|
||
| from ansible.module_utils.basic import * | ||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| #!/bin/bash | ||
|
Contributor
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. This script is lacking comment. Could you also give some samples?
Contributor
Author
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. added comment and usage example
Contributor
Author
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. this change is not for the test. It adds permanent configuration for the testbed. To let it survive the reboot I have to modify start.sh |
||
|
|
||
| # This script updates the SWSSCONFIG_ARGS variable inside the given shell script with the list of files according to given file mask | ||
| # | ||
| # Usage example: | ||
| # to update line | ||
| # SWSSCONFIG_ARGS="some_existing.json " | ||
| # inside the /usr/bin/start.sh with the all json files located in /etc/swss/config.d/acl/ | ||
| # execute: | ||
| # swssconfig_args_update.sh /usr/bin/start.sh /etc/swss/config.d/acl/*.json' | ||
| # | ||
| # example of the resulting line: | ||
| # SWSSCONFIG_ARGS="some_existing.json acl1.json acl2.json " | ||
| # | ||
|
|
||
| OLD_LINE=`cat ${1} | grep SWSSCONFIG_ARGS=` | ||
| STR_ADD=`ls ${2} | sed 's#.*/##' | tr '\n' ' '` | ||
|
|
||
| if echo ${OLD_LINE} | grep -v "${STR_ADD}"; then | ||
| NEW_LINE="${OLD_LINE%\"*}${STR_ADD}\"" | ||
| awk -v old_line="${OLD_LINE}" -v new_line="${NEW_LINE}" '{ if ($0 == old_line) print new_line ; else print $0}' ${1} >/tmp/new_conf && mv /tmp/new_conf ${1} | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| #----------------------------------------- | ||
| # Apply ACL configuration | ||
| #----------------------------------------- | ||
| - set_fact: | ||
| acltb_configs: | ||
| - "{{ 'acltb_persistent_acl_table' }}" | ||
| - "{{ 'acltb_persistent_acl_rules' }}" | ||
|
|
||
| # Gather minigraph facts | ||
| - name: Gathering minigraph facts about the device | ||
| minigraph_facts: host={{ inventory_hostname }} | ||
| become: no | ||
| connection: local | ||
|
|
||
| - name: Print neighbors in minigraph | ||
| debug: msg="{{ minigraph_neighbors }}" | ||
|
|
||
| - name: Read port reverse alias mapping | ||
| set_fact: | ||
| alias_reverse_map: "{{ lookup('file', 'roles/sonicv2/files/ssw/{{ sonic_hwsku }}/alias_reverse_map.json') | from_json }}" | ||
|
|
||
| - block: | ||
| - name: Generate and copy ACL permanent configuration to DUT/swss | ||
| become: true | ||
| template: src={{ item }}.j2 | ||
| dest=/etc/swss/config.d/{{ item }}.json | ||
| mode=0644 | ||
| with_items: | ||
| - "{{ acltb_configs }}" | ||
|
|
||
| - name: Copy start.sh modification script to the DUT/swss | ||
| copy: src=roles/configure/files/helpers/swssconfig_args_update.sh | ||
| dest=/tmp/swssconfig_args_update.sh | ||
|
Contributor
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 noticed you copy the script (swssconfig_args_update.sh) to remote and run it. You may try 'script' module to simplify the steps. |
||
| mode=0755 | ||
|
|
||
| - name: Modify start.sh to apply ACL config on start (table) | ||
| shell: /tmp/swssconfig_args_update.sh /usr/bin/start.sh /etc/swss/config.d/{{ item }}.json | ||
| become: yes | ||
| with_items: | ||
| - "{{ acltb_configs }}" | ||
|
|
||
| - name: Apply ACL configuration | ||
| shell: swssconfig /etc/swss/config.d/{{ item }}.json | ||
| with_items: | ||
| - "{{ acltb_configs }}" | ||
| tags: acltb_configure | ||
|
|
||
| vars: | ||
| ansible_shell_type: docker | ||
| ansible_python_interpreter: docker exec -i swss python | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| - fail: msg="information about testbed missing." | ||
| when: (lo_ip is not defined) or | ||
| (dscp_mode is not defined) | ||
|
|
||
|
Contributor
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. Let me ask a silly question: after the interface is configured following decap rule, is there any way to reset it back to a normal interface? If so how could we do it? |
||
| - fail: msg="Invalid testbed_type value '{{dscp_mode}}'" | ||
| when: dscp_mode not in [ 'pipe','uniform'] | ||
|
|
||
| - block: | ||
| - name: Copy JSON configs into docker filesystem | ||
| template: src=decap_conf.j2 dest=/etc/swss/config.d/decap_config.json | ||
|
|
||
| - name: Copy start.sh modification script to the DUT/swss | ||
| copy: src=roles/configure/files/helpers/swssconfig_args_update.sh | ||
| dest=/tmp/swssconfig_args_update.sh | ||
| mode=0755 | ||
|
|
||
| - name: Modify start.sh to apply decap config on start (rule) | ||
| command: /tmp/swssconfig_args_update.sh /usr/bin/start.sh /etc/swss/config.d/decap_config.json | ||
| become: yes | ||
|
|
||
| - name: Load decap JSON config. | ||
| shell: swssconfig /etc/swss/config.d/decap_config.json | ||
| register: valid_config_upload | ||
| failed_when: valid_config_upload.rc != 0 | ||
| tags: decap | ||
|
|
||
| vars: | ||
| ansible_shell_type: docker | ||
| ansible_python_interpreter: docker exec -i swss python | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #----------------------------------------- | ||
| # Apply ACL permanent configuration | ||
| #----------------------------------------- | ||
|
|
||
| - name: ACL configuration | ||
| include: acltb_permanent_config.yml | ||
| tags: acl | ||
| #----------------------------------------- | ||
| # Apply Everflow permanent configuration | ||
| #----------------------------------------- | ||
|
|
||
| #----------------------------------------- | ||
| # Apply IPinIP permanent configuration | ||
| #----------------------------------------- | ||
| - name: Decap configuration | ||
| include: config_decap.yml | ||
| tags: decap | ||
|
|
Uh oh!
There was an error while loading. Please reload this page.
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.
This file is never used? #Closed
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.
It was used to convert ACL rules list from the xml format to the json file for the swssconfig
If we ever decide to update the list of the rules (from the different xml) we will need this tool