Skip to content

Commit

Permalink
Update for handover
Browse files Browse the repository at this point in the history
  • Loading branch information
louisroyer committed Jan 14, 2025
1 parent 85becf3 commit 34d21f1
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 34 deletions.
2 changes: 1 addition & 1 deletion 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.15
github.com/nextmn/json-api v0.0.16-0.20250114105630-01e517e8726a
github.com/nextmn/logrus-formatter v0.0.1
github.com/nextmn/rfc9433 v0.0.2
github.com/sirupsen/logrus v1.9.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ github.com/nextmn/gopacket-srv6 v0.0.8 h1:oP4wuJ7dOiV/gWmX3zoFcdp2dKdSWLUaxH2fJ3
github.com/nextmn/gopacket-srv6 v0.0.8/go.mod h1:2Tyuo9zsG0bP2IhC4tVRgPRuyUqOgrvEEH9seJSZTlU=
github.com/nextmn/json-api v0.0.15 h1:ZSFr06omGsXtTHT6SWCy7Sc9csNQgwpOibkkdUm0pEA=
github.com/nextmn/json-api v0.0.15/go.mod h1:CQXeNPj9MDGsEExtnqJFIGjLgZAKsmOoO2fy+mep7Ak=
github.com/nextmn/json-api v0.0.16-0.20250114105630-01e517e8726a h1:sOxYlcsNpMXkKew6oR3pTFHjh0DfKDmlPgj0jQgLnh4=
github.com/nextmn/json-api v0.0.16-0.20250114105630-01e517e8726a/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
3 changes: 2 additions & 1 deletion internal/database/api/uplink.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import (
"context"
"net/netip"

"github.com/nextmn/json-api/jsonapi"
"github.com/nextmn/json-api/jsonapi/n4tosrv6"
)

type Uplink interface {
GetUplinkAction(ctx context.Context, UplinkTeid uint32, GnbIp netip.Addr, UeIp netip.Addr, ServiceIp netip.Addr) (n4tosrv6.Action, error)
GetUplinkAction(ctx context.Context, UplinkFTeid jsonapi.Fteid, GnbIp netip.Addr, UeIp netip.Addr, ServiceIp netip.Addr) (n4tosrv6.Action, error)
}
66 changes: 45 additions & 21 deletions internal/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/netip"
"strings"

"github.com/nextmn/json-api/jsonapi"
"github.com/nextmn/json-api/jsonapi/n4tosrv6"

"github.com/gofrs/uuid"
Expand Down Expand Up @@ -93,7 +94,7 @@ func (db *Database) InsertRule(ctx context.Context, r n4tosrv6.Rule) (*uuid.UUID
case "uplink":
var inneripsrc string
var inneripdst string
var outeripsrc string
var outeripsrc []string
if r.Match.Header.InnerIpSrc == nil {
inneripsrc = "0.0.0.0/0"
} else {
Expand All @@ -104,11 +105,13 @@ func (db *Database) InsertRule(ctx context.Context, r n4tosrv6.Rule) (*uuid.UUID
} else {
inneripdst = r.Match.Payload.Dst.String() + "/32"
}
outeripsrc = r.Match.Header.OuterIpSrc.String() + "/32"
for _, i := range r.Match.Header.OuterIpSrc {
outeripsrc = append(outeripsrc, i.String())
}

if stmt, ok := db.stmt["insert_uplink_rule"]; ok {
var id uuid.UUID
err := stmt.QueryRowContext(ctx, r.Enabled, inneripsrc, outeripsrc, r.Match.Header.Teid, inneripdst, pq.Array(srh)).Scan(&id)
err := stmt.QueryRowContext(ctx, r.Enabled, inneripsrc, pq.Array(outeripsrc), r.Match.Header.FTeid.Teid, r.Match.Header.FTeid.Addr.String(), inneripdst, pq.Array(srh)).Scan(&id)
return &id, err
} else {
return nil, fmt.Errorf("Procedure not registered")
Expand Down Expand Up @@ -137,11 +140,12 @@ func (db *Database) GetRule(ctx context.Context, uuid uuid.UUID) (n4tosrv6.Rule,
var enabled bool
var action_srh []string
var match_ue_ip string
var match_gnb_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, &match_gnb_ip, &match_uplink_teid, &match_service_ip)
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)
if err != nil {
return n4tosrv6.Rule{}, err
}
Expand All @@ -152,14 +156,24 @@ func (db *Database) GetRule(ctx context.Context, uuid uuid.UUID) (n4tosrv6.Rule,
if type_uplink {
rule.Type = "uplink"
rule.Match.Header = &n4tosrv6.GtpHeader{}
if match_gnb_ip != nil {
p, err := netip.ParsePrefix(*match_gnb_ip)
if err == nil && p.Bits() == 32 {
rule.Match.Header.OuterIpSrc = p.Addr()

rule.Match.Header.OuterIpSrc = make([]netip.Prefix, 0)
for _, i := range match_gnb_ip {
p, err := netip.ParsePrefix(i)
if err != nil {
return n4tosrv6.Rule{}, err
}
rule.Match.Header.OuterIpSrc = append(rule.Match.Header.OuterIpSrc, p)
}
if match_uplink_teid != nil {
rule.Match.Header.Teid = *match_uplink_teid
if match_uplink_upf != nil && match_uplink_teid != nil {
addr, err := netip.ParseAddr(*match_uplink_upf)
if err != nil {
return n4tosrv6.Rule{}, err
}
rule.Match.Header.FTeid = jsonapi.Fteid{
Teid: *match_uplink_teid,
Addr: addr,
}
}
if match_service_ip != nil {
p, err := netip.ParsePrefix(*match_service_ip)
Expand Down Expand Up @@ -204,8 +218,9 @@ func (db *Database) GetRules(ctx context.Context) (n4tosrv6.RuleMap, error) {
var enabled bool
var action_srh []string
var match_ue_ip string
var match_gnb_ip *string
var match_gnb_ip []string
var match_uplink_teid *uint32
var match_uplink_upf *string
var match_service_ip *string
m := n4tosrv6.RuleMap{}
if stmt, ok := db.stmt["get_all_rules"]; ok {
Expand All @@ -219,7 +234,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, &match_gnb_ip, &match_uplink_teid, &match_service_ip)
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)
if err != nil {
return m, err
}
Expand All @@ -230,14 +245,23 @@ func (db *Database) GetRules(ctx context.Context) (n4tosrv6.RuleMap, error) {
if type_uplink {
rule.Type = "uplink"
rule.Match.Header = &n4tosrv6.GtpHeader{}
if match_gnb_ip != nil {
p, err := netip.ParsePrefix(*match_gnb_ip)
if err == nil && p.Bits() == 32 {
rule.Match.Header.OuterIpSrc = p.Addr()
rule.Match.Header.OuterIpSrc = make([]netip.Prefix, 0)
for _, i := range match_gnb_ip {
p, err := netip.ParsePrefix(i)
if err != nil {
return n4tosrv6.RuleMap{}, err
}
rule.Match.Header.OuterIpSrc = append(rule.Match.Header.OuterIpSrc, p)
}
if match_uplink_teid != nil {
rule.Match.Header.Teid = *match_uplink_teid
if match_uplink_upf != nil && match_uplink_teid != nil {
addr, err := netip.ParseAddr(*match_uplink_upf)
if err != nil {
return n4tosrv6.RuleMap{}, err
}
rule.Match.Header.FTeid = jsonapi.Fteid{
Teid: *match_uplink_teid,
Addr: addr,
}
}
if match_service_ip != nil {
p, err := netip.ParsePrefix(*match_service_ip)
Expand Down Expand Up @@ -316,10 +340,10 @@ func (db *Database) DeleteRule(ctx context.Context, uuid uuid.UUID) error {
}
}

func (db *Database) GetUplinkAction(ctx context.Context, uplinkTeid uint32, gnbIp netip.Addr, ueIp netip.Addr, serviceIp netip.Addr) (n4tosrv6.Action, error) {
func (db *Database) GetUplinkAction(ctx context.Context, uplinkFTeid jsonapi.Fteid, gnbIp netip.Addr, ueIp netip.Addr, serviceIp netip.Addr) (n4tosrv6.Action, error) {
var action_srh []string
if stmt, ok := db.stmt["get_uplink_action"]; ok {
err := stmt.QueryRowContext(ctx, uplinkTeid, gnbIp.String(), ueIp.String(), serviceIp.String()).Scan(pq.Array(&action_srh))
err := stmt.QueryRowContext(ctx, uplinkFTeid.Teid, uplinkFTeid.Addr.String(), gnbIp.String(), ueIp.String(), serviceIp.String()).Scan(pq.Array(&action_srh))
if err != nil {
return n4tosrv6.Action{}, err
}
Expand Down
21 changes: 13 additions & 8 deletions internal/database/database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,25 @@ CREATE TABLE IF NOT EXISTS rule (
enabled BOOL NOT NULL,
action_srh INET ARRAY NOT NULL,
match_ue_ip CIDR NOT NULL,
match_gnb_ip CIDR,
match_gnb_ip CIDR ARRAY,
match_service_ip CIDR,
match_uplink_teid BIGINT
match_uplink_teid BIGINT,
match_uplink_upf INET
);


CREATE OR REPLACE PROCEDURE insert_uplink_rule(
IN in_enabled BOOL, IN in_ue_ip CIDR,
IN in_gnb_ip CIDR, IN in_uplink_teid BIGINT,
IN in_gnb_ip CIDR ARRAY,
IN in_uplink_teid BIGINT, IN in_uplink_upf INET,
IN in_service_ip CIDR,
IN in_srh INET ARRAY,
OUT out_uuid UUID
)
LANGUAGE plpgsql AS $$
BEGIN
INSERT INTO rule(type_uplink, enabled, match_ue_ip, match_gnb_ip, match_uplink_teid, match_service_ip, action_srh)
VALUES(TRUE, in_enabled, in_ue_ip, in_gnb_ip, in_uplink_teid, in_service_ip, in_srh) RETURNING rule.uuid INTO out_uuid;
INSERT INTO rule(type_uplink, enabled, match_ue_ip, match_gnb_ip, match_uplink_teid, match_uplink_upf, match_service_ip, action_srh)
VALUES(TRUE, in_enabled, in_ue_ip, in_gnb_ip, in_uplink_teid, in_uplink_upf, in_service_ip, in_srh) RETURNING rule.uuid INTO out_uuid;
END;$$;

CREATE OR REPLACE PROCEDURE insert_downlink_rule(
Expand Down Expand Up @@ -75,7 +77,8 @@ BEGIN
END;$$;

CREATE OR REPLACE FUNCTION get_uplink_action(
IN in_uplink_teid BIGINT, IN in_gnb_ip INET,
IN in_uplink_teid BIGINT, IN in_uplink_upf INET,
IN in_gnb_ip INET,
IN in_ue_ip INET, IN in_service_ip INET
)
RETURNS TABLE (
Expand All @@ -86,7 +89,8 @@ BEGIN
RETURN QUERY SELECT rule.action_srh AS "t_action_srh"
FROM rule
WHERE (rule.match_uplink_teid = in_uplink_teid
AND rule.match_gnb_ip && in_gnb_ip
AND rule.match_uplink_upf && in_uplink_upf
AND in_gnb_ip <<= any (rule.match_gnb_ip)
AND rule.match_ue_ip && in_ue_ip
AND rule.match_service_ip && in_service_ip
AND rule.enabled = TRUE
Expand Down Expand Up @@ -116,8 +120,9 @@ RETURNS TABLE (
t_enabled BOOL,
t_action_srh INET ARRAY,
t_match_ue_ip CIDR,
t_match_gnb_ip CIDR,
t_match_gnb_ip CIDR ARRAY,
t_match_uplink_teid BIGINT,
t_match_uplink_upf INET,
t_match_service_ip CIDR
)
AS $$
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.

3 changes: 2 additions & 1 deletion internal/netfunc/headend-gtp4-ctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

gopacket_gtp "github.com/nextmn/gopacket-gtp"
gopacket_srv6 "github.com/nextmn/gopacket-srv6"
"github.com/nextmn/json-api/jsonapi"
"github.com/nextmn/rfc9433/encoding"

"github.com/google/gopacket"
Expand Down Expand Up @@ -141,7 +142,7 @@ func (h HeadendGTP4WithCtrl) Handle(ctx context.Context, packet []byte) ([]byte,
innerHeaderSrcIPv4 := netip.AddrFrom4([4]byte{inner.SrcIP[0], inner.SrcIP[1], inner.SrcIP[2], inner.SrcIP[3]})
innerHeaderDstIPv4 := netip.AddrFrom4([4]byte{inner.DstIP[0], inner.DstIP[1], inner.DstIP[2], inner.DstIP[3]})

action, err := h.db.GetUplinkAction(ctx, teid, gnb_ip, innerHeaderSrcIPv4, innerHeaderDstIPv4)
action, err := h.db.GetUplinkAction(ctx, jsonapi.Fteid{Teid: teid, Addr: dest_addr}, gnb_ip, innerHeaderSrcIPv4, innerHeaderDstIPv4)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 34d21f1

Please sign in to comment.