Skip to content
Merged
Show file tree
Hide file tree
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
28 changes: 14 additions & 14 deletions acl+fwstate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ rules:
# === IPv4 ===

# Create state for outgoing TCP to port 80
- action: CreateState
counter: ""
- actions:
- kind: CreateState
devices: []
dst_ports:
- from: 80
Expand All @@ -32,8 +32,8 @@ rules:
vlan_ranges: []

# Check state for return traffic
- action: CheckState
counter: ""
- actions:
- kind: CheckState
devices: []
dst_ports:
- from: 0
Expand All @@ -51,8 +51,8 @@ rules:
vlan_ranges: []

# Create state for outgoing UDP to port 80
- action: CreateState
counter: ""
- actions:
- kind: CreateState
devices: []
dst_ports:
- from: 80
Expand All @@ -70,8 +70,8 @@ rules:
vlan_ranges: []

# Check state for return UDP traffic
- action: CheckState
counter: ""
- actions:
- kind: CheckState
devices: []
dst_ports:
- from: 0
Expand All @@ -91,8 +91,8 @@ rules:
# === IPv6 ===

# Create state for outgoing TCPv6 to port 80
- action: CreateState
counter: ""
- actions:
- kind: CreateState
devices: []
dst_ports:
- from: 80
Expand All @@ -110,8 +110,8 @@ rules:
vlan_ranges: []

# Check state for return TCPv6 traffic
- action: CheckState
counter: ""
- actions:
- kind: CheckState
devices: []
dst_ports:
- from: 0
Expand All @@ -133,8 +133,8 @@ rules:
# Allow external fwstate sync frames (IPv6 UDP to multicast ff02::1 port 9999).
# These packets are processed by the fwstate module to create external state
# entries and then dropped.
- action: Allow
counter: ""
- actions:
- kind: Allow
devices: []
dst_ports:
- from: 9999
Expand Down
20 changes: 12 additions & 8 deletions modules/acl/api/controlplane.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,19 +458,23 @@ acl_module_config_update(

for (uint32_t idx = 0; idx < rule_count; ++idx) {
struct acl_rule *acl_rule = acl_rules + idx;
targets[idx].action = acl_rule->action;
if (acl_rule->counter[0] == '\0')
struct acl_action *terminal =
&acl_rule->actions[acl_rule->action_count - 1];
targets[idx].action = terminal->id;

const char *counter_name = terminal->counter;
char default_counter[COUNTER_NAME_LEN];
if (counter_name[0] == '\0') {
snprintf(
acl_rule->counter,
sizeof(acl_rule->counter),
default_counter,
sizeof(default_counter),
"rule %d",
idx
);
counter_name = default_counter;
}
if ((targets[idx].counter_id = counter_registry_register(
&cp_module->counter_registry,
acl_rule->counter,
2,
err
&cp_module->counter_registry, counter_name, 2, err
)) == (uint64_t)-1) {
goto error_target;
}
Expand Down
9 changes: 7 additions & 2 deletions modules/acl/api/controlplane.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ acl_module_config_init(
void
acl_module_config_free(struct cp_module *cp_module);

struct acl_rule {
uint64_t action;
struct acl_action {
uint64_t id;
char counter[COUNTER_NAME_LEN];
};

struct acl_rule {
struct acl_action *actions;
uint64_t action_count;

struct filter_devices devices;
struct filter_vlan_ranges vlan_ranges;
Expand Down
61 changes: 39 additions & 22 deletions modules/acl/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,13 @@ struct SerializableRule {
proto_ranges: Vec<String>,
vlan_ranges: Vec<String>,
devices: Vec<String>,
action: Option<SerializableAction>,
actions: Vec<SerializableAction>,
}

#[derive(Serialize)]
struct SerializableAction {
kind: String,
counter: String,
keep_state: bool,
kind: i32,
}

#[derive(Tabled)]
Expand Down Expand Up @@ -387,8 +386,17 @@ enum ActionKind {
Allow,
Deny,
Count,
SkipTo,
CheckState,
CreateState,
Log,
}

#[derive(Debug, Serialize, Deserialize)]
struct ACLAction {
kind: ActionKind,
#[serde(default)]
counter: String,
}

#[derive(Debug, Serialize, Deserialize)]
Expand All @@ -400,8 +408,7 @@ struct ACLRule {
proto_ranges: Vec<Range>,
vlan_ranges: Vec<Range>,
devices: Vec<String>,
counter: String,
action: ActionKind,
actions: Vec<ACLAction>,
}

/// Converts a YAML `Range` to a protobuf `PortRange`, validating that
Expand Down Expand Up @@ -470,18 +477,23 @@ impl TryFrom<ACLRule> for aclpb::Rule {
.collect::<Result<_, _>>()?,
vlan_ranges: acl_rule.vlan_ranges.iter().map(vlan_range).collect::<Result<_, _>>()?,
devices: acl_rule.devices.iter().cloned().map(Device::from).collect(),
action: Some(aclpb::Action {
counter: acl_rule.counter,
keep_state: false,
kind: match acl_rule.action {
ActionKind::Allow => aclpb::ActionKind::Pass,
ActionKind::Deny => aclpb::ActionKind::Deny,
ActionKind::Count => aclpb::ActionKind::Count,
ActionKind::CheckState => aclpb::ActionKind::CheckState,
ActionKind::CreateState => aclpb::ActionKind::CreateState,
}
.into(),
}),
actions: acl_rule
.actions
.iter()
.map(|a| aclpb::Action {
kind: match a.kind {
ActionKind::Allow => aclpb::ActionKind::Pass,
ActionKind::Deny => aclpb::ActionKind::Deny,
ActionKind::Count => aclpb::ActionKind::Count,
ActionKind::SkipTo => aclpb::ActionKind::Skipto,
ActionKind::CheckState => aclpb::ActionKind::CheckState,
ActionKind::CreateState => aclpb::ActionKind::CreateState,
ActionKind::Log => aclpb::ActionKind::Log,
}
.into(),
counter: a.counter.clone(),
})
.collect(),
})
}
}
Expand Down Expand Up @@ -573,11 +585,16 @@ impl ACLService {
.map(|r| format!("{}-{}", r.from, r.to))
.collect(),
devices: rule.devices.iter().map(|d| d.name.clone()).collect(),
action: rule.action.map(|a| SerializableAction {
counter: a.counter,
keep_state: a.keep_state,
kind: a.kind,
}),
actions: rule
.actions
.iter()
.map(|a| SerializableAction {
kind: aclpb::ActionKind::try_from(a.kind)
.map(|k| k.as_str_name().to_string())
.unwrap_or_else(|_| a.kind.to_string()),
counter: a.counter.clone(),
})
.collect(),
})
.collect(),
};
Expand Down
9 changes: 5 additions & 4 deletions modules/acl/controlplane/aclpb/acl.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ message ShowConfigResponse {
}

message Rule {
Action action = 1;
repeated Action actions = 1;

repeated filterpb.Device devices = 2;
repeated filterpb.VlanRange vlan_ranges = 3;
Expand All @@ -52,16 +52,17 @@ message Rule {
message Action {
ActionKind kind = 1;
string counter = 2;
bool keep_state = 3;
}

// Defines possible actions for matched traffic
enum ActionKind {
ACTION_KIND_PASS = 0;
ACTION_KIND_DENY = 1;
ACTION_KIND_COUNT = 2;
ACTION_KIND_CHECK_STATE = 3;
ACTION_KIND_CREATE_STATE = 4;
ACTION_KIND_SKIPTO = 3;
ACTION_KIND_CHECK_STATE = 4;
ACTION_KIND_CREATE_STATE = 5;
ACTION_KIND_LOG = 6;
}

// Delete config with specified name.
Expand Down
31 changes: 24 additions & 7 deletions modules/acl/controlplane/ffi.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,13 @@ func (m *ModuleConfig) AsFFIModule() ffi.ModuleConfig {
return m.ptr
}

type AclAction struct {
ID uint64
Counter string
}

type AclRule struct {
Action uint64
Counter string
Actions []AclAction
Devices filter.Devices
VlanRanges filter.VlanRanges
Src4s filter.IPNets
Expand All @@ -71,14 +75,27 @@ type AclRule struct {
DstPortRanges filter.PortRanges
}

// CBuildActions writes the C representation of AclActions into dst.
func CBuildActions(dst *C.struct_acl_rule, actions []AclAction, pinner *runtime.Pinner) {
if len(actions) == 0 {
return
}
cActions := make([]C.struct_acl_action, len(actions))
for idx, a := range actions {
cActions[idx].id = C.uint64_t(a.ID)
cCounter := C.CString(a.Counter)
C.strncpy(&cActions[idx].counter[0], cCounter, C.COUNTER_NAME_LEN)
C.free(unsafe.Pointer(cCounter))
}
pinner.Pin(&cActions[0])
dst.actions = &cActions[0]
dst.action_count = C.uint64_t(len(cActions))
}

func (m *AclRule) CBuild(pinner *runtime.Pinner) C.struct_acl_rule {
cRule := C.struct_acl_rule{}

cRule.action = C.uint64_t(m.Action)
cCounter := C.CString(m.Counter)
C.strncpy(&cRule.counter[0], cCounter, C.COUNTER_NAME_LEN)
C.free(unsafe.Pointer(cCounter))

CBuildActions(&cRule, m.Actions, pinner)
filter.CBuildDevices(&cRule.devices, m.Devices, pinner)
filter.CBuildVlanRanges(&cRule.vlan_ranges, m.VlanRanges, pinner)
filter.CBuildNet4s(&cRule.src_net4s, m.Src4s, pinner)
Expand Down
45 changes: 28 additions & 17 deletions modules/acl/controlplane/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,33 @@ func (m *ACLService) newHandlerTracker(name string) *handlerMetricTracker {
)
}

////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////
func terminalAction(protoActions []*aclpb.Action) AclAction {
const (
cACLActionAllow = 0
cACLActionDeny = 1
cACLActionCheckState = 3
cACLActionCreateState = 4
)

if len(protoActions) == 0 {
return AclAction{ID: cACLActionAllow}
}

a := protoActions[len(protoActions)-1]
switch a.GetKind() {
case aclpb.ActionKind_ACTION_KIND_PASS:
return AclAction{ID: cACLActionAllow, Counter: a.GetCounter()}
case aclpb.ActionKind_ACTION_KIND_DENY:
return AclAction{ID: cACLActionDeny, Counter: a.GetCounter()}
case aclpb.ActionKind_ACTION_KIND_CHECK_STATE:
return AclAction{ID: cACLActionCheckState, Counter: a.GetCounter()}
case aclpb.ActionKind_ACTION_KIND_CREATE_STATE:
return AclAction{ID: cACLActionCreateState, Counter: a.GetCounter()}
default:
return AclAction{ID: cACLActionDeny, Counter: a.GetCounter()}
}
}

func convertRules(reqRules []*aclpb.Rule) ([]AclRule, error) {
rules := make([]AclRule, 0, len(reqRules))
Expand Down Expand Up @@ -106,7 +132,7 @@ func convertRules(reqRules []*aclpb.Rule) ([]AclRule, error) {
}

rule := AclRule{
Counter: reqRule.Action.Counter,
Actions: []AclAction{terminalAction(reqRule.Actions)},
Devices: devices,
VlanRanges: vlanRanges,
Src4s: src4s,
Expand All @@ -118,21 +144,6 @@ func convertRules(reqRules []*aclpb.Rule) ([]AclRule, error) {
DstPortRanges: dstPortRanges,
}

switch reqRule.Action.Kind {
case aclpb.ActionKind_ACTION_KIND_PASS:
rule.Action = 0 // ACL_ACTION_ALLOW
case aclpb.ActionKind_ACTION_KIND_DENY:
rule.Action = 1 // ACL_ACTION_DENY
case aclpb.ActionKind_ACTION_KIND_COUNT:
rule.Action = 2 // ACL_ACTION_COUNT
case aclpb.ActionKind_ACTION_KIND_CHECK_STATE:
rule.Action = 3 // ACL_ACTION_CHECK_STATE
case aclpb.ActionKind_ACTION_KIND_CREATE_STATE:
rule.Action = 4 // ACL_ACTION_CREATE_STATE
default:
rule.Action = 1 // ACL_ACTION_DENY
}

rules = append(rules, rule)
}
return rules, nil
Expand Down
Loading
Loading