Skip to content

Commit

Permalink
MINOR: Add support for set-fc-mark, set-fc-tos
Browse files Browse the repository at this point in the history
And also set-bc-mark and set-bc-tos. Those actions reaplce
set-mark and set-tos, which are now deprecated in HAProxy.
  • Loading branch information
oliwer committed Feb 23, 2024
1 parent e9c14fd commit ffe6142
Show file tree
Hide file tree
Showing 19 changed files with 658 additions and 21 deletions.
76 changes: 76 additions & 0 deletions parsers/actions/set-bc-mark.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2024 HAProxy Technologies
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

//nolint:dupl
package actions

import (
"fmt"
"math"
"strings"

"github.com/haproxytech/config-parser/v5/common"
"github.com/haproxytech/config-parser/v5/types"
)

type SetBcMark struct {
Expr common.Expression
Cond string
CondTest string
Comment string
}

func (f *SetBcMark) Parse(parts []string, parserType types.ParserType, comment string) error {
if comment != "" {
f.Comment = comment
}
if len(parts) < 3 {
return fmt.Errorf("not enough params")
}
var command []string
switch parserType {
case types.HTTP:
command = parts[2:]
case types.TCP:
command = parts[3:]
}
command, condition := common.SplitRequest(command)

if len(command) > 0 {
if len(command) == 1 && !validateUnsignedNumber(command[0], math.MaxUint32) {
return fmt.Errorf("number '%s' is not a valid mark value", command[0])
}
expr := common.Expression{}
err := expr.Parse(command)
if err != nil {
return fmt.Errorf("not enough params")
}
f.Expr = expr
}
if len(condition) > 1 {
f.Cond = condition[0]
f.CondTest = strings.Join(condition[1:], " ")
}
return nil
}

func (f *SetBcMark) String() string {
return common.SmartJoin("set-bc-mark", f.Expr.String(), f.Cond, f.CondTest)
}

func (f *SetBcMark) GetComment() string {
return f.Comment
}
76 changes: 76 additions & 0 deletions parsers/actions/set-bc-tos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2024 HAProxy Technologies
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

//nolint:dupl
package actions

import (
"fmt"
"math"
"strings"

"github.com/haproxytech/config-parser/v5/common"
"github.com/haproxytech/config-parser/v5/types"
)

type SetBcTos struct {
Expr common.Expression
Cond string
CondTest string
Comment string
}

func (f *SetBcTos) Parse(parts []string, parserType types.ParserType, comment string) error {
if comment != "" {
f.Comment = comment
}
if len(parts) < 3 {
return fmt.Errorf("not enough params")
}
var command []string
switch parserType {
case types.HTTP:
command = parts[2:]
case types.TCP:
command = parts[3:]
}
command, condition := common.SplitRequest(command)

if len(command) > 0 {
if len(command) == 1 && !validateUnsignedNumber(command[0], math.MaxUint8) {
return fmt.Errorf("number '%s' is not a valid TOS value", command[0])
}
expr := common.Expression{}
err := expr.Parse(command)
if err != nil {
return fmt.Errorf("not enough params")
}
f.Expr = expr
}
if len(condition) > 1 {
f.Cond = condition[0]
f.CondTest = strings.Join(condition[1:], " ")
}
return nil
}

func (f *SetBcTos) String() string {
return common.SmartJoin("set-bc-tos", f.Expr.String(), f.Cond, f.CondTest)
}

func (f *SetBcTos) GetComment() string {
return f.Comment
}
76 changes: 76 additions & 0 deletions parsers/actions/set-fc-mark.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2024 HAProxy Technologies
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

//nolint:dupl
package actions

import (
"fmt"
"math"
"strings"

"github.com/haproxytech/config-parser/v5/common"
"github.com/haproxytech/config-parser/v5/types"
)

type SetFcMark struct {
Expr common.Expression
Cond string
CondTest string
Comment string
}

func (f *SetFcMark) Parse(parts []string, parserType types.ParserType, comment string) error {
if comment != "" {
f.Comment = comment
}
if len(parts) < 3 {
return fmt.Errorf("not enough params")
}
var command []string
switch parserType {
case types.HTTP:
command = parts[2:]
case types.TCP:
command = parts[3:]
}
command, condition := common.SplitRequest(command)

if len(command) > 0 {
if len(command) == 1 && !validateUnsignedNumber(command[0], math.MaxUint32) {
return fmt.Errorf("number '%s' is not a valid mark value", command[0])
}
expr := common.Expression{}
err := expr.Parse(command)
if err != nil {
return fmt.Errorf("not enough params")
}
f.Expr = expr
}
if len(condition) > 1 {
f.Cond = condition[0]
f.CondTest = strings.Join(condition[1:], " ")
}
return nil
}

func (f *SetFcMark) String() string {
return common.SmartJoin("set-fc-mark", f.Expr.String(), f.Cond, f.CondTest)
}

func (f *SetFcMark) GetComment() string {
return f.Comment
}
94 changes: 94 additions & 0 deletions parsers/actions/set-fc-tos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
Copyright 2024 HAProxy Technologies
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package actions

import (
"fmt"
"math"
"strconv"
"strings"

"github.com/haproxytech/config-parser/v5/common"
"github.com/haproxytech/config-parser/v5/types"
)

type SetFcTos struct {
Expr common.Expression
Cond string
CondTest string
Comment string
}

func (f *SetFcTos) Parse(parts []string, parserType types.ParserType, comment string) error {
if comment != "" {
f.Comment = comment
}
if len(parts) < 3 {
return fmt.Errorf("not enough params")
}
var command []string
switch parserType {
case types.HTTP:
command = parts[2:]
case types.TCP:
command = parts[3:]
}
command, condition := common.SplitRequest(command)

if len(command) > 0 {
if len(command) == 1 && !validateUnsignedNumber(command[0], math.MaxUint8) {
return fmt.Errorf("number '%s' is not a valid TOS value", command[0])
}
expr := common.Expression{}
err := expr.Parse(command)
if err != nil {
return fmt.Errorf("not enough params")
}
f.Expr = expr
}
if len(condition) > 1 {
f.Cond = condition[0]
f.CondTest = strings.Join(condition[1:], " ")
}
return nil
}

func (f *SetFcTos) String() string {
return common.SmartJoin("set-fc-tos", f.Expr.String(), f.Cond, f.CondTest)
}

func (f *SetFcTos) GetComment() string {
return f.Comment
}

// Test if the given string is an unsigned integer between zero and "max".
// The number can be in decimal or hexadecimal (0x).
// If the parsing failed, assume the string was an Expr and return true.
func validateUnsignedNumber(text string, max int64) bool {
var n int64
var err error
if strings.HasPrefix(text, "0x") {
n, err = strconv.ParseInt(text, 16, 64)
} else {
n, err = strconv.ParseInt(text, 10, 64)
}
if err != nil {
// Assume it was an expression, not a number.
return true
}
return n >= 0 && n <= max
}
8 changes: 8 additions & 0 deletions parsers/http/http-request.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ func (h *Requests) Parse(line string, parts []string, comment string) (string, e
err = h.ParseHTTPRequest(&httpActions.WaitForHandshake{}, parts, comment)
case "set-bandwidth-limit":
err = h.ParseHTTPRequest(&actions.SetBandwidthLimit{}, parts, comment)
case "set-bc-mark":
err = h.ParseHTTPRequest(&actions.SetBcMark{}, parts, comment)
case "set-bc-tos":
err = h.ParseHTTPRequest(&actions.SetBcTos{}, parts, comment)
case "set-fc-mark":
err = h.ParseHTTPRequest(&actions.SetFcMark{}, parts, comment)
case "set-fc-tos":
err = h.ParseHTTPRequest(&actions.SetFcTos{}, parts, comment)
default:
switch {
case strings.HasPrefix(parts[1], "track-sc"):
Expand Down
4 changes: 4 additions & 0 deletions parsers/http/http-response.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ func (h *Responses) Parse(line string, parts []string, comment string) (string,
err = h.ParseHTTPResponse(&httpActions.WaitForBody{}, parts, comment)
case "set-bandwidth-limit":
err = h.ParseHTTPResponse(&actions.SetBandwidthLimit{}, parts, comment)
case "set-fc-mark":
err = h.ParseHTTPResponse(&actions.SetFcMark{}, parts, comment)
case "set-fc-tos":
err = h.ParseHTTPResponse(&actions.SetFcTos{}, parts, comment)
default:
switch {
case strings.HasPrefix(parts[1], "track-sc"):
Expand Down
4 changes: 4 additions & 0 deletions parsers/tcp/types/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ func (f *Connection) Parse(parts []string, comment string) error {
err = f.ParseAction(&actions.SetSrcPort{}, parts)
case "set-dst-port":
err = f.ParseAction(&actions.SetDstPort{}, parts)
case "set-fc-mark":
err = f.ParseAction(&actions.SetFcMark{}, parts)
case "set-fc-tos":
err = f.ParseAction(&actions.SetFcTos{}, parts)
default:
switch {
case strings.HasPrefix(parts[2], "track-sc"):
Expand Down
8 changes: 8 additions & 0 deletions parsers/tcp/types/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ func (f *Content) Parse(parts []string, comment string) error { //nolint:gocyclo
err = f.ParseAction(&tcpActions.SwitchMode{}, parts)
case "close":
err = f.ParseAction(&tcpActions.Close{}, parts)
case "set-bc-mark":
err = f.ParseAction(&actions.SetBcMark{}, parts)
case "set-bc-tos":
err = f.ParseAction(&actions.SetBcTos{}, parts)
case "set-fc-mark":
err = f.ParseAction(&actions.SetFcMark{}, parts)
case "set-fc-tos":
err = f.ParseAction(&actions.SetFcTos{}, parts)
default:
switch {
case strings.HasPrefix(parts[2], "track-sc"):
Expand Down
4 changes: 4 additions & 0 deletions parsers/tcp/types/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func (f *Session) Parse(parts []string, comment string) error {
err = f.ParseAction(&actions.Reject{}, parts)
case "silent-drop":
err = f.ParseAction(&actions.SilentDrop{}, parts)
case "set-fc-mark":
err = f.ParseAction(&actions.SetFcMark{}, parts)
case "set-fc-tos":
err = f.ParseAction(&actions.SetFcTos{}, parts)
default:
switch {
case strings.HasPrefix(parts[2], "track-sc"):
Expand Down
Loading

0 comments on commit ffe6142

Please sign in to comment.