diff --git a/internal/pfcpctl/commands/sessions.go b/internal/pfcpctl/commands/sessions.go index 67f0b87..c505097 100644 --- a/internal/pfcpctl/commands/sessions.go +++ b/internal/pfcpctl/commands/sessions.go @@ -16,7 +16,7 @@ type commonArgs struct { BaseID int `short:"i" long:"baseID" default:"1" description:"The base ID to use"` UePool string `short:"u" long:"ue-pool" default:"17.0.0.0/24" description:"The UE pool address"` GnBAddress string `short:"g" long:"gnb-addr" description:"The UE pool address"` - AppFilterString string `short:"a" long:"app-filter" description:"Specify an application filter. Format: ':/:-:' . e.g. 'udp:10.0.0.0/8:80-88:allow'"` + AppFilterString string `short:"a" long:"app-filter" description:"Specify an application filter. Format: '{ip | udp | tcp}:{IPv4 Prefix | any}:{- | any}:{allow | deny}' . e.g. 'udp:10.0.0.0/8:80-88:allow'"` QFI uint8 `short:"q" long:"qfi" description:"The QFI value for QERs. Max value 64."` } diff --git a/internal/pfcpsim/helpers.go b/internal/pfcpsim/helpers.go index 28577da..4737076 100644 --- a/internal/pfcpsim/helpers.go +++ b/internal/pfcpsim/helpers.go @@ -13,7 +13,8 @@ import ( "github.com/wmnsk/go-pfcp/ie" ) -const sdfFilterFormat = "permit out %v from %v to assigned %v-%v" +const sdfFilterFormatWPort = "permit out %v from %v to assigned %v-%v" +const sdfFilterFormatWOPort = "permit out %v from %v to assigned" func connectPFCPSim() error { if sim == nil { @@ -89,41 +90,47 @@ func parseAppFilter(filter string) (string, uint8, error) { proto, ipNetAddr, portRange, action := result[0], result[1], result[2], result[3] - if !(proto == "ip" || proto == "udp" || proto == "tcp") { - return "", 0, pfcpsim.NewInvalidFormatError("Unsupported or unknown protocol.") - } - - _, _, err := net.ParseCIDR(ipNetAddr) - if err != nil { - return "", 0, pfcpsim.NewInvalidFormatError("IP and subnet mask.", err) - } - - portList := strings.Split(portRange, "-") - if !(len(portList) == 2) { - return "", 0, pfcpsim.NewInvalidFormatError("Port range. Please make sure to use dash '-' to separate the two ports") + var gateStatus uint8 + switch action { + case "allow": + gateStatus = ie.GateStatusOpen + case "deny": + gateStatus = ie.GateStatusClosed + default: + return "", 0, pfcpsim.NewInvalidFormatError("Action. Please make sure to use 'allow' or 'deny'") } - lowerPort, err := strconv.Atoi(portList[0]) - if err != nil { - return "", 0, pfcpsim.NewInvalidFormatError("Port range.", err) + if !(proto == "ip" || proto == "udp" || proto == "tcp") { + return "", 0, pfcpsim.NewInvalidFormatError("Unsupported or unknown protocol.") } - upperPort, err := strconv.Atoi(portList[1]) - if err != nil { - return "", 0, pfcpsim.NewInvalidFormatError("Port range.", err) + if ipNetAddr != "any" { + _, _, err := net.ParseCIDR(ipNetAddr) + if err != nil { + return "", 0, pfcpsim.NewInvalidFormatError("IP and subnet mask.", err) + } } + if portRange != "any" { + portList := strings.Split(portRange, "-") + if !(len(portList) == 2) { + return "", 0, pfcpsim.NewInvalidFormatError("Port range. Please make sure to use dash '-' to separate the two ports") + } - if lowerPort > upperPort { - return "", 0, pfcpsim.NewInvalidFormatError("Port range. Lower port is greater than upper port") - } + lowerPort, err := strconv.Atoi(portList[0]) + if err != nil { + return "", 0, pfcpsim.NewInvalidFormatError("Port range.", err) + } - if !(action == "allow" || action == "deny") { - return "", 0, pfcpsim.NewInvalidFormatError("Action. Please make sure to use 'allow' or 'deny'") - } + upperPort, err := strconv.Atoi(portList[1]) + if err != nil { + return "", 0, pfcpsim.NewInvalidFormatError("Port range.", err) + } - if action == "allow" { - return fmt.Sprintf(sdfFilterFormat, proto, ipNetAddr, lowerPort, upperPort), ie.GateStatusOpen, nil + if lowerPort > upperPort { + return "", 0, pfcpsim.NewInvalidFormatError("Port range. Lower port is greater than upper port") + } + return fmt.Sprintf(sdfFilterFormatWPort, proto, ipNetAddr, lowerPort, upperPort), gateStatus, nil + } else { + return fmt.Sprintf(sdfFilterFormatWOPort, proto, ipNetAddr), gateStatus, nil } - - return fmt.Sprintf(sdfFilterFormat, proto, ipNetAddr, lowerPort, upperPort), ie.GateStatusClosed, nil } diff --git a/internal/pfcpsim/helpers_test.go b/internal/pfcpsim/helpers_test.go index 166cf21..06a8197 100644 --- a/internal/pfcpsim/helpers_test.go +++ b/internal/pfcpsim/helpers_test.go @@ -44,6 +44,42 @@ func Test_parseAppFilter(t *testing.T) { gateStatus: ie.GateStatusClosed, }, }, + {name: "Correct app filter with deny-all policy", + args: &args{ + filterString: "ip:0.0.0.0/0:any:deny", + }, + want: &want{ + SDFFilter: "permit out ip from 0.0.0.0/0 to assigned", + gateStatus: ie.GateStatusClosed, + }, + }, + {name: "Correct app filter with deny-all policy 2", + args: &args{ + filterString: "ip:any:any:deny", + }, + want: &want{ + SDFFilter: "permit out ip from any to assigned", + gateStatus: ie.GateStatusClosed, + }, + }, + {name: "Correct app filter with allow-all policy", + args: &args{ + filterString: "ip:any:any:allow", + }, + want: &want{ + SDFFilter: "permit out ip from any to assigned", + gateStatus: ie.GateStatusOpen, + }, + }, + {name: "Correct app filter with allow-all policy 2", + args: &args{ + filterString: "ip:0.0.0.0/0:any:allow", + }, + want: &want{ + SDFFilter: "permit out ip from 0.0.0.0/0 to assigned", + gateStatus: ie.GateStatusOpen, + }, + }, {name: "incorrect app filter bad protocol", args: &args{ filterString: "test:10.0.0.0/8:80-80:allow",