Skip to content
Snippets Groups Projects
Commit 482b2d0c authored by Georgios Katsikas's avatar Georgios Katsikas
Browse files

feat: support for more NFs and fixes

parent 6b0edee8
No related branches found
No related tags found
No related merge requests found
......@@ -140,6 +140,15 @@ def chk_address_ipv4(ip_addr : str):
except ValueError:
return False
def chk_prefix_len_ipv4(ip_prefix_len : int):
"""
Check whether input integer is a valid IPv4 address prefix length.
:param ip_prefix_len: IPv4 address prefix length
:return: boolean status
"""
return 0 <= ip_prefix_len <= 32
def chk_address_ipv6(ip_addr : str):
"""
Check whether input string is a valid IPv6 address or not.
......
......@@ -24,19 +24,37 @@ SD-Fabric docs: https://docs.sd-fabric.org/master/index.html
import time
import logging
import struct
from common.proto.context_pb2 import ConfigActionEnum, ConfigRule
from common.tools.object_factory.ConfigRule import json_config_rule
from common.type_checkers.Checkers import chk_address_mac, chk_vlan_id, \
chk_address_ipv4, chk_transport_port
from random import randint
from typing import List, Tuple
from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, Device, EndPoint
from common.tools.object_factory.ConfigRule import json_config_rule
from common.type_checkers.Checkers import chk_address_mac, chk_vlan_id, \
chk_address_ipv4, chk_prefix_len_ipv4, chk_transport_port
from service.service.task_scheduler.TaskExecutor import TaskExecutor
LOGGER = logging.getLogger(__name__)
# Common service handler settings
TARGET_P4_ARCH = "target_p4_arch"
SWITCH_DATAPLANE_ID_MAP = "switch_dataplane_id_map"
SWITCH_INFO = "switch_info"
ARCH = "arch"
DPID = "dpid"
MAC = "mac"
IP = "ip"
PORT = "port" # Dataplane port
PORT_ID = "port_id"
PORT_TYPE = "port_type"
VLAN_ID = "vlan_id"
RECIRCULATION_PORT_LIST = "recirculation_port_list"
PORT_LIST = "port_list"
PORT_PREFIX = "port-"
ROUTING_LIST = "routing_list"
MAC_SRC = "mac_src"
MAC_DST = "mac_dst"
IPV4_SRC = "ipv4_src"
IPV4_DST = "ipv4_dst"
IPV4_PREFIX_LEN = "ipv4_prefix_len"
TRN_PORT_SRC = "trn_port_src" # Transport network port (TCP, UDP)
TRN_PORT_DST = "trn_port_dst"
# P4 architectures
TARGET_ARCH_TNA = "tna"
......@@ -140,7 +158,7 @@ def generate_random_mac() -> str:
return mac_str
def prefix_to_hex_mask(prefix_len):
def prefix_to_hex_mask(prefix_len : int) -> str:
# Calculate the binary mask
binary_mask = (1 << 32) - (1 << (32 - prefix_len))
......@@ -156,6 +174,30 @@ def sleep_for(time_sec : int) -> None:
assert time_sec > 0, "Invalid sleep period in seconds"
time.sleep(time_sec)
def find_port_id_in_endpoint(endpoint : EndPoint, target_endpoint_uuid : str) -> int: # type: ignore
assert endpoint, "Invalid device endpoint"
endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
assert endpoint_uuid, "Invalid device endpoint UUID"
if endpoint_uuid == target_endpoint_uuid:
try:
dpid = int(endpoint.name) # P4 devices have integer dataplane port IDs
assert dpid > 0, "Invalid device endpoint DPID"
except Exception as ex:
LOGGER.error(ex)
return -1
return dpid
return -1
def find_port_id_in_endpoint_list(endpoint_list : List, target_endpoint_uuid : str) -> int:
assert endpoint_list, "Invalid device endpoint list"
for endpoint in endpoint_list:
result = find_port_id_in_endpoint(endpoint, target_endpoint_uuid)
if result != -1:
return result
return -1
################################################################################################################
### Rule generation methods
################################################################################################################
......@@ -173,6 +215,9 @@ def rules_set_up_port_ingress(
assert port_type.lower() in PORT_TYPES_STR_VALID, "Invalid port type to configure ingress port"
assert chk_vlan_id(vlan_id), "Invalid VLAN ID to configure ingress port"
# VLAN support if 1
vlan_is_valid = 1 if vlan_id != VLAN_DEF else 0
rule_no = cache_rule(TABLE_INGRESS_VLAN, action)
port_type_int = PORT_TYPE_MAP[port_type.lower()]
......@@ -192,7 +237,7 @@ def rules_set_up_port_ingress(
},
{
'match-field': 'vlan_is_valid',
'match-value': '0'
'match-value': str(vlan_is_valid)
}
],
'action-name': 'FabricIngress.filtering.permit_with_internal_vlan',
......@@ -270,7 +315,7 @@ def rules_set_up_fwd_classifier(
'match-value': str(ingress_port)
},
{
'match-field': 'eth_type',
'match-field': 'ip_eth_type',
'match-value': eth_type
}
],
......@@ -278,10 +323,10 @@ def rules_set_up_fwd_classifier(
'action-params': [
{
'action-param': 'fwd_type',
'action-value': str(FORWARDING_TYPE_UNICAST_IPV4)
'action-value': str(fwd_type)
},
],
'priority': 10
'priority': 1
}
)
)
......@@ -294,7 +339,7 @@ def rules_set_up_port(
fwd_type : int,
vlan_id : int,
action : ConfigActionEnum, # type: ignore
eth_type=ETHER_TYPE_IPV4):
eth_type=ETHER_TYPE_IPV4) -> List [Tuple]:
rules_list = []
rules_list.extend(
......@@ -377,12 +422,8 @@ def rules_set_up_fwd_bridging(
def rules_set_up_next_output_simple(
egress_port : int,
eth_src : str,
eth_dst : str,
action : ConfigActionEnum) -> List [Tuple]: # type: ignore
assert egress_port >= 0, "Invalid outport to configure next output simple"
assert chk_address_mac(eth_src), "Invalid source Ethernet address to configure next output simple"
assert chk_address_mac(eth_dst), "Invalid destination Ethernet address to configure next output simple"
rule_no = cache_rule(TABLE_NEXT_SIMPLE, action)
......@@ -478,9 +519,11 @@ def rules_set_up_next_output_hashed(
def rules_set_up_routing(
ipv4_dst : str,
ipv4_prefix_len : int,
egress_port : int,
action : ConfigActionEnum) -> List [Tuple]: # type: ignore
assert chk_address_ipv4(ipv4_dst), "Invalid destination IPv4 address to configure routing"
assert chk_prefix_len_ipv4(ipv4_prefix_len), "Invalid IPv4 prefix length"
assert egress_port >= 0, "Invalid outport to configure routing"
rule_no = cache_rule(TABLE_ROUTING_V4, action)
......@@ -495,7 +538,7 @@ def rules_set_up_routing(
'match-fields': [
{
'match-field': 'ipv4_dst',
'match-value': ipv4_dst
'match-value': ipv4_dst + "/" + str(ipv4_prefix_len)
}
],
'action-name': 'FabricIngress.forwarding.set_next_id_routing_v4',
......@@ -694,11 +737,14 @@ def rules_set_up_acl_filter_host(
ingress_port : int,
ip_address : str,
prefix_len : int,
ip_direction : str,
action : ConfigActionEnum) -> List [Tuple]: # type: ignore
assert ingress_port >= 0, "Invalid ingress port to configure ACL"
assert chk_address_ipv4(ip_address), "Invalid IP address to configure ACL"
assert 0 < prefix_len <= 32, "Invalid IP address prefix length to configure ACL"
ip_match = "ipv4_src" if ip_direction == "src" else "ipv4_dst"
prefix_len_hex = prefix_to_hex_mask(prefix_len)
rule_no = cache_rule(TABLE_ACL, action)
......@@ -716,7 +762,7 @@ def rules_set_up_acl_filter_host(
'match-value': str(ingress_port)
},
{
'match-field': 'ipv4_src',
'match-field': ip_match,
'match-value': '%s&&&%s' % (ip_address, prefix_len_hex)
}
],
......@@ -732,10 +778,13 @@ def rules_set_up_acl_filter_host(
def rules_set_up_acl_filter_port(
ingress_port : int,
transport_port : int,
transport_direction : str,
action : ConfigActionEnum) -> List [Tuple]: # type: ignore
assert ingress_port >= 0, "Invalid ingress port to configure ACL"
assert chk_transport_port(transport_port), "Invalid transport port to configure ACL"
trn_match = "l4_sport" if transport_direction == "src" else "l4_dport"
rule_no = cache_rule(TABLE_ACL, action)
rules_acl = []
......@@ -751,7 +800,7 @@ def rules_set_up_acl_filter_port(
'match-value': str(ingress_port)
},
{
'match-field': 'l4_dport',
'match-field': trn_match,
'match-value': str(transport_port)
}
],
......@@ -772,7 +821,10 @@ def rules_set_up_acl_filter_port(
### Rule management methods
################################################################################################################
def apply_rules(task_executor, device_obj, json_config_rules):
def apply_rules(
task_executor : TaskExecutor,
device_obj : Device, # type: ignore
json_config_rules : List): # type: ignore
applied_rules = 0
failed_rules = 0
total_rules = len(json_config_rules)
......@@ -802,9 +854,9 @@ def apply_rules(task_executor, device_obj, json_config_rules):
except Exception as ex:
LOGGER.error("Error while applying rule #{}: {}".format(i, ex))
failed_rules += 1
raise Exception(ex)
LOGGER.info("Batch rules: {}/{} applied".format(applied_rules, total_rules))
LOGGER.info("Batch rules: {}/{} failed".format(failed_rules, total_rules))
LOGGER.debug("Batch rules: {}/{} applied".format(applied_rules, total_rules))
return applied_rules, failed_rules
......
......@@ -203,7 +203,7 @@ class TaskExecutor:
self, service_id : ServiceId, config_key : str, config_value : str
):
service_configRule = ServiceConfigRule()
service_configRule.service_id.CopyFrom( service_id)
service_configRule.service_id.CopyFrom(service_id)
service_configRule.configrule_custom.resource_key = config_key
service_configRule.configrule_custom.resource_value = config_value
try:
......
......@@ -28,9 +28,9 @@ P4_DEV_NB = 1
CONNECTION_RULES = 3
ENDPOINT_RULES = 3
INT_RULES = 19
L2_RULES = 8
L3_RULES = 8
ACL_RULES = 1
L2_RULES = 10
L3_RULES = 4
ACL_RULES = 2
DATAPLANE_RULES_NB_INT_B1 = 5
DATAPLANE_RULES_NB_INT_B2 = 6
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment