Skip to content

Commit e2f1bc6

Browse files
authored
Merge pull request #115 from digitalocean/nbouliane/multipath
add multipath action
2 parents 2a0f99c + 2a4aaa3 commit e2f1bc6

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

ovs/action.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func StripVLAN() Action {
181181
// printf-style patterns for marshaling and unmarshaling actions.
182182
const (
183183
patConnectionTracking = "ct(%s)"
184+
patMultipath = "multipath(%s,%d,%s,%d,%d,%s)"
184185
patConjunction = "conjunction(%d,%d/%d)"
185186
patModDataLinkDestination = "mod_dl_dst:%s"
186187
patModDataLinkSource = "mod_dl_src:%s"
@@ -439,6 +440,46 @@ func (a *outputFieldAction) GoString() string {
439440
return fmt.Sprintf("ovs.OutputField(%q)", a.field)
440441
}
441442

443+
// Multipath returns a MultipathAction instance.
444+
//
445+
// Hashes fields using `basis` as a universal hash parameter, then
446+
// applies multipath link selection `algorithm` (with parameter `arg`)
447+
// to choose one of `n_links` output links numbered 0 through n_links
448+
// minus 1, and stores the link into `dst`, which must be a field or
449+
// subfield in the syntax described under ``Field Specifications’’
450+
// above.
451+
// https://www.openvswitch.org/support/dist-docs/ovs-actions.7.txt
452+
func Multipath(fields string, basis int, algorithm string, nlinks int, arg int, dst string) Action {
453+
return &multipathAction{
454+
fields: fields,
455+
basis: basis,
456+
algorithm: algorithm,
457+
nlinks: nlinks,
458+
arg: arg,
459+
dst: dst,
460+
}
461+
}
462+
463+
// MarshalText converts the Bucket to its string representation
464+
func (me *multipathAction) MarshalText() ([]byte, error) {
465+
return bprintf(patMultipath, me.fields, me.basis, me.algorithm, me.nlinks, me.arg, me.dst), nil
466+
}
467+
468+
// MultipathAction represents a multipath hashing rule
469+
type multipathAction struct {
470+
fields string
471+
basis int
472+
algorithm string
473+
nlinks int
474+
arg int
475+
dst string
476+
}
477+
478+
// GoString implements Action.
479+
func (me *multipathAction) GoString() string {
480+
return fmt.Sprintf("ovs.Multipath(%q, %q, %q, %q, %q, %q)", me.fields, me.basis, me.algorithm, me.nlinks, me.arg, me.dst)
481+
}
482+
442483
// Conjunction associates a flow with a certain conjunction ID to match on more than
443484
// one dimension across multiple set matches.
444485
func Conjunction(id int, dimensionNumber int, dimensionSize int) Action {

ovs/action_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,40 @@ func TestSetTunnel(t *testing.T) {
535535
}
536536
}
537537

538+
func TestMultipath(t *testing.T) {
539+
var tests = []struct {
540+
desc string
541+
a Action
542+
action string
543+
err error
544+
}{
545+
{
546+
desc: "set multipath OK",
547+
a: Multipath("symmetric_l3l4+udp", 1024, "hrw", 2, 0, "reg0"),
548+
action: "multipath(symmetric_l3l4+udp,1024,hrw,2,0,reg0)",
549+
},
550+
}
551+
552+
for _, tt := range tests {
553+
t.Run(tt.desc, func(t *testing.T) {
554+
action, err := tt.a.MarshalText()
555+
556+
if want, got := tt.err, err; want != got {
557+
t.Fatalf("unexpected error:\n- want: %v\n- got: %v",
558+
want, got)
559+
}
560+
if err != nil {
561+
return
562+
}
563+
564+
if want, got := tt.action, string(action); want != got {
565+
t.Fatalf("unexpected Action:\n- want: %q\n- got: %q",
566+
want, got)
567+
}
568+
})
569+
}
570+
}
571+
538572
func TestConjunction(t *testing.T) {
539573
var tests = []struct {
540574
desc string

0 commit comments

Comments
 (0)