fix rules

This commit is contained in:
anlicheng 2026-02-28 17:22:41 +08:00
parent 2c4ce65e7b
commit be053ef8b4
9 changed files with 44 additions and 76 deletions

View File

@ -30,13 +30,11 @@
-record(rule, { -record(rule, {
rule_id :: integer(), rule_id :: integer(),
policy_id :: integer(),
network_id :: integer(), network_id :: integer(),
access_rule_id :: integer(),
src_policy_id :: integer(), src_policy_id :: integer(),
dst_policy_id :: integer(), dst_policy_id :: integer(),
proto :: integer(), proto :: integer(),
port :: integer(), port :: integer(),
action, action = allow :: allow | deny,
created_at = 0 :: integer() created_at = 0 :: integer()
}). }).

View File

@ -1,21 +0,0 @@
-module(identity_ets).
-include("policy.hrl").
-export([init/0]).
-export([lookup/1, insert/1]).
-define(TABLE, identity_ets_table).
init() ->
ets:new(?TABLE, [named_table, ordered_set, public, {keypos, 2}, {read_concurrency, true}]).
lookup(IdentityId) when is_integer(IdentityId) ->
case ets:lookup(?TABLE, IdentityId) of
[Identity] ->
{ok, Identity};
[] ->
error
end.
insert(Identity = #identity{}) ->
true = ets:insert(?TABLE, Identity).

View File

@ -4,15 +4,13 @@
-export([init/0]). -export([init/0]).
-export([get_policies/1, insert/1]). -export([get_policies/1, insert/1]).
-define(TABLE, identity_policy_ets_table).
init() -> init() ->
ets:new(?TABLE, [named_table, bag, public, {keypos, 2}, {read_concurrency, true}]). ets:new(identity_policy, [named_table, bag, public, {keypos, 2}, {read_concurrency, true}]).
-spec get_policies(IdentityId :: integer()) -> [PolicyId :: integer()]. -spec get_policies(IdentityId :: integer()) -> [PolicyId :: integer()].
get_policies(IdentityId) when is_integer(IdentityId) -> get_policies(IdentityId) when is_integer(IdentityId) ->
Records = ets:lookup(?TABLE, IdentityId), Records = ets:lookup(identity_policy, IdentityId),
lists:map(fun(#identity_policy{policy_id = PolicyId}) -> PolicyId end, Records). lists:map(fun(#identity_policy{policy_id = PolicyId}) -> PolicyId end, Records).
insert(IdentityPolicy = #identity_policy{}) -> insert(IdentityPolicy = #identity_policy{}) ->
true = ets:insert(?TABLE, IdentityPolicy). true = ets:insert(identity_policy, IdentityPolicy).

View File

@ -1,21 +0,0 @@
%%%-------------------------------------------------------------------
%%% @author anlicheng
%%% @copyright (C) 2026, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 28. 2 2026 15:55
%%%-------------------------------------------------------------------
-module(policy).
-author("anlicheng").
%% API
-export([]).
get_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_integer(DstIdentityId) ->
SrcPolicies = identity_policy_ets:get_policies(SrcIdentityId),
DstPolicies = identity_policy_ets:get_policies(DstIdentityId),
ok.

View File

@ -1,16 +0,0 @@
-module(policy_ets).
-include("policy.hrl").
-export([init/0]).
-export([lookup/1, insert/1]).
-define(TABLE, policy_ets_table).
init() ->
ets:new(?TABLE, [named_table, ordered_set, public, {keypos, 2}, {read_concurrency, true}]).
lookup(PolicyId) when is_integer(PolicyId) ->
Records = ets:lookup(?TABLE, PolicyId).
insert(Policy = #policy{}) ->
true = ets:insert(?TABLE, Policy).

View File

@ -6,14 +6,26 @@
init() -> init() ->
ets:new(rule_table, [named_table, ordered_set, public, {keypos, 2}, {read_concurrency, true}]), ets:new(rule_table, [named_table, ordered_set, public, {keypos, 2}, {read_concurrency, true}]),
ets:new(rule_index, [named_table, set, public, {read_concurrency, true}]). ets:new(rule_index, [named_table, bag, public, {read_concurrency, true}]).
-spec get_rules(SrcPolicyIds :: any(), DstPolicyIds :: any()) -> {ok, [{Proto :: integer(), Port :: integer()}]}.
get_rules(SrcPolicyIds, DstPolicyIds) when is_list(SrcPolicyIds), is_list(DstPolicyIds) -> get_rules(SrcPolicyIds, DstPolicyIds) when is_list(SrcPolicyIds), is_list(DstPolicyIds) ->
MatchKeys = [{S, D, '_'} || S <- SrcPolicyIds, D <- DstPolicyIds], MatchKeys = [{S, D, '_'} || S <- SrcPolicyIds, D <- DstPolicyIds],
Records = lists:flatmap(fun({S, D, _}) -> ets:match_object(rule_index, {S, D, '_'}) end, MatchKeys), Records = lists:flatmap(fun({S, D, _}) -> ets:match_object(rule_index, {S, D, '_'}) end, MatchKeys),
Rules = lists:flatmap(fun({_, _, RuleId}) -> ets:lookup(rule_table, RuleId) end, Records), Rules = lists:flatmap(fun({_, _, RuleId}) -> ets:lookup(rule_table, RuleId) end, Records),
{ok, Rules}.
S = lists:foldl(fun(Rule, S) ->
case Rule of
#rule{action = allow, proto = Proto, port = Port} ->
sets:add_element({Proto, Port}, S);
_ ->
S
end
end, sets:new(), Rules),
{ok, sets:to_list(S)}.
insert(Rule = #rule{src_policy_id = SrcPolicyId, dst_policy_id = DstPolicyId, rule_id = RuleId}) -> insert(Rule = #rule{src_policy_id = SrcPolicyId, dst_policy_id = DstPolicyId, rule_id = RuleId}) ->
ets:insert(rule_table, Rule), ets:insert(rule_table, Rule),
logger:debug("rule_index: ~p", [{SrcPolicyId, DstPolicyId, RuleId}]),
ets:insert(rule_index, {SrcPolicyId, DstPolicyId, RuleId}). ets:insert(rule_index, {SrcPolicyId, DstPolicyId, RuleId}).

View File

@ -201,16 +201,18 @@ handle_event(info, {frame, <<?PACKET_QUERY_INFO, Body/binary>>}, registered, #st
keep_state_and_data keep_state_and_data
end; end;
%% TODO
handle_event(info, {frame, <<?PACKET_POLICY_REQUEST, Body/binary>>}, registered, #state{stream = Stream, network_pid = NetworkPid}) when is_pid(NetworkPid) -> handle_event(info, {frame, <<?PACKET_POLICY_REQUEST, Body/binary>>}, registered, #state{stream = Stream, network_pid = NetworkPid}) when is_pid(NetworkPid) ->
maybe maybe
PolicyRequest = catch sdlan_pb:decode_msg(Body, sdl_policy_request), PolicyRequest = catch sdlan_pb:decode_msg(Body, sdl_policy_request),
#sdl_policy_request{src_identity_id = SrcIdentityId, dst_identity_id = DstIdentityId, version = Version} ?= PolicyRequest, #sdl_policy_request{src_identity_id = SrcIdentityId, dst_identity_id = DstIdentityId, version = Version} ?= PolicyRequest,
{ok, Rules} = get_rules(SrcIdentityId, DstIdentityId),
RuleBin = iolist_to_binary(lists:map(fun({Proto, Port}) -> <<Proto:8, Port:16>> end, Rules)),
PolicyResponsePkt = sdlan_pb:encode_msg(#sdl_policy_response { PolicyResponsePkt = sdlan_pb:encode_msg(#sdl_policy_response {
src_identity_id = SrcIdentityId, src_identity_id = SrcIdentityId,
dst_identity_id = DstIdentityId, dst_identity_id = DstIdentityId,
version = Version, version = Version,
rules = <<1, 80:16, 2, 9090:16>> rules = RuleBin
}), }),
quic_send(Stream, <<?PACKET_POLICY_REPLY, PolicyResponsePkt/binary>>) quic_send(Stream, <<?PACKET_POLICY_REPLY, PolicyResponsePkt/binary>>)
end, end,
@ -325,3 +327,9 @@ quic_send(Stream, Packet) when is_binary(Packet) ->
{error, Reason} -> {error, Reason} ->
exit({quic_send_failed, Reason}) exit({quic_send_failed, Reason})
end. end.
-spec get_rules(SrcIdentityId :: integer(), DstIdentityId :: integer()) -> {ok, [{Proto :: integer(), Port :: integer()}]}.
get_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_integer(DstIdentityId) ->
SrcPolicyIds = identity_policy_ets:get_policies(SrcIdentityId),
DstPolicyIds = identity_policy_ets:get_policies(DstIdentityId),
rule_ets:get_rules(SrcPolicyIds, DstPolicyIds).

View File

@ -19,6 +19,10 @@ start(_StartType, _StartArgs) ->
sdlan_domain_regedit:init(), sdlan_domain_regedit:init(),
dns_pending_wheel:start(), dns_pending_wheel:start(),
%%
identity_policy_ets:init(),
rule_ets:init(),
start_http_server(), start_http_server(),
sdlan_sup:start_link(). sdlan_sup:start_link().

View File

@ -97,20 +97,20 @@ sync_rule() ->
sync_rule0(0). sync_rule0(0).
sync_rule0(RuleIdOffset) -> sync_rule0(RuleIdOffset) ->
{ok, Rows} = mysql_pool:get_all(mysql_sdlan, <<"select * from rule where rule_id > ? order by rule_id asc limit 5000">>, [RuleIdOffset]), {ok, Rows} = mysql_pool:get_all(mysql_sdlan, <<"select * from rule where rule_id > ? order by rule_id asc limit 5000">>, [RuleIdOffset]),
logger:debug("rule rows: ~p", [Rows]),
case length(Rows) > 0 of case length(Rows) > 0 of
true -> true ->
RuleIds = lists:map(fun(#{<<"rule_id">> := RuleId, <<"policy_id">> := PolicyId, <<"network_id">> := NetworkId, RuleIds = lists:map(fun(#{<<"rule_id">> := RuleId, <<"network_id">> := NetworkId,
<<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId, <<"proto">> := Proto, <<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId, <<"proto">> := Proto,
<<"port">> := Port, <<"action">> := Action, <<"created_at">> := CreatedAt}) -> <<"port">> := Port, <<"action">> := Action, <<"created_at">> := CreatedAt}) ->
identity_policy_ets:insert(#rule{ rule_ets:insert(#rule{
rule_id = RuleId, rule_id = RuleId,
policy_id = PolicyId,
network_id = NetworkId, network_id = NetworkId,
src_policy_id = SrcPolicyId, src_policy_id = SrcPolicyId,
dst_policy_id = DstPolicyId, dst_policy_id = DstPolicyId,
proto = Proto, proto = Proto,
port = Port, port = Port,
action = Action, action = format_action(Action),
created_at = CreatedAt created_at = CreatedAt
}), }),
RuleId RuleId
@ -120,3 +120,9 @@ sync_rule0(RuleIdOffset) ->
false -> false ->
ok ok
end. end.
-spec format_action(binary()) -> atom().
format_action(<<"allow">>) ->
allow;
format_action(_) ->
deny.