Skip to content

Commit

Permalink
Source GTP4 for downlink
Browse files Browse the repository at this point in the history
  • Loading branch information
louisroyer committed Jan 17, 2025
1 parent ce2077c commit 1e06abb
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 31 deletions.
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/lib/pq v1.10.9
github.com/nextmn/gopacket-gtp v0.0.8
github.com/nextmn/gopacket-srv6 v0.0.8
github.com/nextmn/json-api v0.0.16
github.com/nextmn/json-api v0.0.17
github.com/nextmn/logrus-formatter v0.0.1
github.com/nextmn/rfc9433 v0.0.2
github.com/sirupsen/logrus v1.9.3
Expand All @@ -21,14 +21,14 @@ require (

require (
github.com/bytedance/sonic v1.12.7 // indirect
github.com/bytedance/sonic/loader v0.2.2 // indirect
github.com/bytedance/sonic/loader v0.2.3 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.0.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.23.0 // indirect
github.com/go-playground/validator/v10 v10.24.0 // indirect
github.com/goccy/go-json v0.10.4 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
Expand All @@ -46,5 +46,5 @@ require (
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.36.2 // indirect
google.golang.org/protobuf v1.36.3 // indirect
)
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ
github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q=
github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.2 h1:jxAJuN9fOot/cyz5Q6dUuMJF5OqQ6+5GfA8FjjQ0R4o=
github.com/bytedance/sonic/loader v0.2.2/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0=
github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
Expand All @@ -25,8 +25,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
Expand Down Expand Up @@ -57,8 +57,8 @@ github.com/nextmn/gopacket-gtp v0.0.8 h1:NF3GRPSdDjmoTeyN584NwbJJJ3tHwPZysZE2ma/
github.com/nextmn/gopacket-gtp v0.0.8/go.mod h1:94jLjLU04IOVTKBXUP09MXZCgmlizqmflU2ion1ht6E=
github.com/nextmn/gopacket-srv6 v0.0.8 h1:oP4wuJ7dOiV/gWmX3zoFcdp2dKdSWLUaxH2fJ3TYAwA=
github.com/nextmn/gopacket-srv6 v0.0.8/go.mod h1:2Tyuo9zsG0bP2IhC4tVRgPRuyUqOgrvEEH9seJSZTlU=
github.com/nextmn/json-api v0.0.16 h1:RU5eTVvnwrYK0Zmh/EhdO7Q3A+hUWjavg9ytJknaYTU=
github.com/nextmn/json-api v0.0.16/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.17 h1:u8Q32fxy7xh1XCGG/QrtZIN/8NVDU6Q9W8CnaMZdZq0=
github.com/nextmn/json-api v0.0.17/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/logrus-formatter v0.0.1 h1:Bsf78jjiEESc+rV8xE6IyKj4frDPGMwXFNrLQzm6A1E=
github.com/nextmn/logrus-formatter v0.0.1/go.mod h1:vdSZ+sIcSna8vjbXkSFxsnsKHqRwaUEed4JCPcXoGyM=
github.com/nextmn/rfc9433 v0.0.2 h1:6FjMY+Qy8MNXQ0PPxezUsyXDxJiCbTp5j3OcXQgIQh8=
Expand Down Expand Up @@ -117,8 +117,8 @@ golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
65 changes: 56 additions & 9 deletions internal/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,14 @@ func (db *Database) InsertRule(ctx context.Context, r n4tosrv6.Rule) (*uuid.UUID
} else {
dst = r.Match.Payload.Dst.String() + "/32"
}
err := stmt.QueryRowContext(ctx, r.Enabled, dst, pq.Array(srh)).Scan(&id)
src_ipv6 := "::"
if r.Action.SourceGtp4 != nil {
src_ipv6 = r.Action.SourceGtp4.String()
} else {
return nil, fmt.Errorf("Empty SourceGtp4 for downlink Action")
}

err := stmt.QueryRowContext(ctx, r.Enabled, dst, pq.Array(srh), src_ipv6).Scan(&id)
return &id, err
} else {
return nil, fmt.Errorf("Procedure not registered")
Expand All @@ -139,13 +146,14 @@ func (db *Database) GetRule(ctx context.Context, uuid uuid.UUID) (n4tosrv6.Rule,
var type_uplink bool
var enabled bool
var action_srh []string
var action_source_gtp4 *string
var match_ue_ip string
var match_gnb_ip []string
var match_service_ip *string
var match_uplink_teid *uint32
var match_uplink_upf *string
if stmt, ok := db.stmt["get_rule"]; ok {
err := stmt.QueryRowContext(ctx, uuid.String()).Scan(&type_uplink, &enabled, pq.Array(&action_srh), &match_ue_ip, pq.Array(&match_gnb_ip), &match_uplink_teid, &match_uplink_upf, &match_service_ip)
err := stmt.QueryRowContext(ctx, uuid.String()).Scan(&type_uplink, &enabled, pq.Array(&action_srh), &action_source_gtp4, &match_ue_ip, pq.Array(&match_gnb_ip), &match_uplink_teid, &match_uplink_upf, &match_service_ip)
if err != nil {
return n4tosrv6.Rule{}, err
}
Expand Down Expand Up @@ -202,8 +210,18 @@ func (db *Database) GetRule(ctx context.Context, uuid uuid.UUID) (n4tosrv6.Rule,
return n4tosrv6.Rule{}, err
}

if action_source_gtp4 == nil {
return n4tosrv6.Rule{}, fmt.Errorf("Empty SourceGtp4 for downlink rule")
}

source_gtp4, err := netip.ParseAddr(*action_source_gtp4)
if err != nil {
return n4tosrv6.Rule{}, err
}

rule.Action = n4tosrv6.Action{
SRH: *srh,
SRH: *srh,
SourceGtp4: &source_gtp4,
}

return rule, err
Expand All @@ -217,6 +235,7 @@ func (db *Database) GetRules(ctx context.Context) (n4tosrv6.RuleMap, error) {
var type_uplink bool
var enabled bool
var action_srh []string
var action_source_gtp4 *string
var match_ue_ip string
var match_gnb_ip []string
var match_uplink_teid *uint32
Expand All @@ -234,7 +253,7 @@ func (db *Database) GetRules(ctx context.Context) (n4tosrv6.RuleMap, error) {
// avoid looping if no longer necessary
return n4tosrv6.RuleMap{}, ctx.Err()
default:
err := rows.Scan(&uuid, &type_uplink, &enabled, pq.Array(&action_srh), &match_ue_ip, pq.Array(&match_gnb_ip), &match_uplink_teid, &match_uplink_upf, &match_service_ip)
err := rows.Scan(&uuid, &type_uplink, &enabled, pq.Array(&action_srh), &action_source_gtp4, &match_ue_ip, pq.Array(&match_gnb_ip), &match_uplink_teid, &match_uplink_upf, &match_service_ip)
if err != nil {
return m, err
}
Expand Down Expand Up @@ -285,14 +304,23 @@ func (db *Database) GetRules(ctx context.Context) (n4tosrv6.RuleMap, error) {
}
}
}
if action_source_gtp4 == nil {
return n4tosrv6.RuleMap{}, fmt.Errorf("Empty SourceGtp4 for downlink rule")
}

source_gtp4, err := netip.ParseAddr(*action_source_gtp4)
if err != nil {
return n4tosrv6.RuleMap{}, err
}

srh, err := n4tosrv6.NewSRH(action_srh)
if err != nil {
return n4tosrv6.RuleMap{}, err
}

rule.Action = n4tosrv6.Action{
SRH: *srh,
SRH: *srh,
SourceGtp4: &source_gtp4,
}
m[uuid] = rule
}
Expand Down Expand Up @@ -351,36 +379,55 @@ func (db *Database) GetUplinkAction(ctx context.Context, uplinkFTeid jsonapi.Fte
if err != nil {
return n4tosrv6.Action{}, err
}
return n4tosrv6.Action{SRH: *srh}, err
return n4tosrv6.Action{
SRH: *srh,
}, err
} else {
return n4tosrv6.Action{}, fmt.Errorf("Procedure not registered")
}
}

func (db *Database) GetDownlinkAction(ctx context.Context, ueIp netip.Addr) (n4tosrv6.Action, error) {
var action_srh []string
var action_source_gtp4 *string
if stmt, ok := db.stmt["get_downlink_action"]; ok {
err := stmt.QueryRowContext(ctx, ueIp.String()).Scan(pq.Array(&action_srh))
err := stmt.QueryRowContext(ctx, ueIp.String()).Scan(pq.Array(&action_srh), &action_source_gtp4)
if err != nil {
return n4tosrv6.Action{}, err
}
srh, err := n4tosrv6.NewSRH(action_srh)
if err != nil {
return n4tosrv6.Action{}, err
}
return n4tosrv6.Action{SRH: *srh}, err
if action_source_gtp4 == nil {
return n4tosrv6.Action{}, fmt.Errorf("Empty SourceGtp4 for downlink rule")
}
source_gtp4, err := netip.ParseAddr(*action_source_gtp4)
if err != nil {
return n4tosrv6.Action{}, err
}
return n4tosrv6.Action{
SRH: *srh,
SourceGtp4: &source_gtp4,
}, err
} else {
return n4tosrv6.Action{}, fmt.Errorf("Procedure not registered")
}
}

func (db *Database) UpdateAction(ctx context.Context, uuidRule uuid.UUID, action n4tosrv6.Action) error {
srh := []string{}
source_gtp4 := "::"
if action.SourceGtp4 != nil {
source_gtp4 = action.SourceGtp4.String()
} else {
return fmt.Errorf("Empty SourceGtp4 for downlink rule")
}
for _, ip := range action.SRH {
srh = append(srh, ip.String())
}
if stmt, ok := db.stmt["update_action"]; ok {
_, err := stmt.ExecContext(ctx, uuidRule.String(), pq.Array(srh))
_, err := stmt.ExecContext(ctx, uuidRule.String(), pq.Array(srh), source_gtp4)
return err
} else {
return fmt.Errorf("Procedure not registered")
Expand Down
23 changes: 16 additions & 7 deletions internal/database/database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ CREATE TABLE IF NOT EXISTS rule (
type_uplink BOOL NOT NULL,
enabled BOOL NOT NULL,
action_srh INET ARRAY NOT NULL,
action_source_gtp4 INET,
match_ue_ip CIDR NOT NULL,
match_gnb_ip CIDR ARRAY,
match_service_ip CIDR,
Expand All @@ -33,12 +34,13 @@ END;$$;
CREATE OR REPLACE PROCEDURE insert_downlink_rule(
IN in_enabled BOOL, IN in_ue_ip CIDR,
IN in_srh INET ARRAY,
IN in_source_gtp4 INET,
OUT out_uuid UUID
)
LANGUAGE plpgsql AS $$
BEGIN
INSERT INTO rule(type_uplink, enabled, match_ue_ip, action_srh)
VALUES(FALSE, in_enabled, in_ue_ip, in_srh) RETURNING rule.uuid INTO out_uuid;
INSERT INTO rule(type_uplink, enabled, match_ue_ip, action_srh, action_source_gtp4)
VALUES(FALSE, in_enabled, in_ue_ip, in_srh, in_source_gtp4) RETURNING rule.uuid INTO out_uuid;
END;$$;


Expand Down Expand Up @@ -78,11 +80,13 @@ END;$$;

CREATE OR REPLACE PROCEDURE update_action(
IN in_uuid UUID,
IN in_srh INET ARRAY
IN in_srh INET ARRAY,
IN in_source_gtp4 INET
)
LANGUAGE plpgsql AS $$
BEGIN
UPDATE rule SET action_srh = in_srh WHERE rule.uuid = in_uuid;
UPDATE rule SET action_source_gtp4 = in_source_gtp4 WHERE rule.uuid = in_uuid;
END;$$;

CREATE OR REPLACE FUNCTION get_uplink_action(
Expand Down Expand Up @@ -111,11 +115,12 @@ CREATE OR REPLACE FUNCTION get_downlink_action(
IN in_ue_ip_address INET
)
RETURNS TABLE (
t_action_srh INET ARRAY
t_action_srh INET ARRAY,
t_action_source_gtp4 INET
)
AS $$
BEGIN
RETURN QUERY SELECT rule.action_srh AS "t_action_srh"
RETURN QUERY SELECT rule.action_srh AS "t_action_srh", rule.action_source_gtp4 AS "t_action_source_gtp4"
FROM rule
WHERE (rule.type_uplink = FALSE AND rule.enabled = TRUE
AND match_ue_ip && in_ue_ip_address);
Expand All @@ -128,6 +133,7 @@ RETURNS TABLE (
t_type_uplink BOOL,
t_enabled BOOL,
t_action_srh INET ARRAY,
t_action_source_gtp4 INET,
t_match_ue_ip CIDR,
t_match_gnb_ip CIDR ARRAY,
t_match_uplink_teid BIGINT,
Expand All @@ -137,7 +143,8 @@ RETURNS TABLE (
AS $$
BEGIN
RETURN QUERY SELECT type_uplink AS "t_type_uplink", enabled AS "t_enabled",
action_srh AS "t_action_srh", match_ue_ip AS "t_match_ue_ip", match_gnb_ip AS "t_match_gnb_ip",
action_srh AS "t_action_srh", action_source_gtp4 AS "t_action_source_gtp4",
match_ue_ip AS "t_match_ue_ip", match_gnb_ip AS "t_match_gnb_ip",
match_uplink_teid AS "t_match_uplink_teid", match_uplink_upf AS "t_match_uplink_upf",
match_service_ip AS "t_match_service_ip"
FROM rule
Expand All @@ -150,6 +157,7 @@ RETURNS TABLE (
t_type_uplink BOOL,
t_enabled BOOL,
t_action_srh INET ARRAY,
t_action_source_gtp4 INET,
t_match_ue_ip CIDR,
t_match_gnb_ip CIDR ARRAY,
t_match_uplink_teid BIGINT,
Expand All @@ -160,7 +168,8 @@ AS $$
BEGIN
RETURN QUERY SELECT uuid AS "t_uuid", type_uplink AS "t_type_uplink",
enabled AS "t_enabled",
action_srh AS "t_action_srh", match_ue_ip AS "t_match_ue_ip", match_gnb_ip AS "t_match_gnb_ip",
action_srh AS "t_action_srh", action_source_gtp4 AS "t_action_source_gtp4",
match_ue_ip AS "t_match_ue_ip", match_gnb_ip AS "t_match_gnb_ip",
match_uplink_teid AS "t_match_uplink_teid", match_uplink_upf AS "t_match_uplink_upf",
match_service_ip AS "t_match_service_ip"
FROM rule;
Expand Down
4 changes: 2 additions & 2 deletions internal/database/database_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion internal/netfunc/headend-encaps-ctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ func (h HeadendEncapsWithCtrl) Handle(ctx context.Context, packet []byte) ([]byt
if err != nil {
return nil, err
}
srgw_gtp_ip := netip.MustParseAddr("10.3.0.1") // FIXME: dont hardcode
if action.SourceGtp4 == nil {
return nil, fmt.Errorf("Empty SourceGtp4 for downlink Action")
}
srgw_gtp_ip := *action.SourceGtp4
ipv6Src := encoding.NewMGTP4IPv6Src(h.srcPrefix, srgw_gtp_ip.As4(), 2152) // FIXME:dont hardcode udp port number to 2152
src, err := ipv6Src.Marshal()
if err != nil {
Expand Down

0 comments on commit 1e06abb

Please sign in to comment.