Skip to content

Commit 80c06a4

Browse files
authored
Merge pull request #36 from digitalocean/nshrader/resubmit-port
ovs: Introduce separate action for ResubmitPort
2 parents 71b8f37 + a6e5969 commit 80c06a4

File tree

4 files changed

+111
-20
lines changed

4 files changed

+111
-20
lines changed

ovs/action.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ var (
4141
// errLoadSetFieldZero is returned when Load or SetField is called with value and/or
4242
// field set to empty strings.
4343
errLoadSetFieldZero = errors.New("value and/or field for action load or set_field are empty")
44+
45+
// errResubmitPortInvalid is returned when ResubmitPort is given a port number that is
46+
// invalid per the openflow spec.
47+
errResubmitPortInvalid = errors.New("resubmit port must be between 0 and 65279 inclusive")
4448
)
4549

4650
// Action strings in lower case, as those are compared to the lower case letters
@@ -385,6 +389,36 @@ type resubmitAction struct {
385389
table int
386390
}
387391

392+
// ResubmitPort resubmits a packet into the current table with its context modified
393+
// to look like it originated from the specified openflow port ID.
394+
func ResubmitPort(port int) Action {
395+
return &resubmitPortAction{
396+
port: port,
397+
}
398+
}
399+
400+
// A resubmitPortAction is an Action which is used by ConneectionTracking.
401+
type resubmitPortAction struct {
402+
port int
403+
}
404+
405+
// MarshalText implements Action.
406+
func (a *resubmitPortAction) MarshalText() ([]byte, error) {
407+
// Largest valid port ID is 0xfeff per openflow spec.
408+
if a.port < 0 || a.port > 0xfeff {
409+
return nil, errResubmitPortInvalid
410+
}
411+
412+
p := strconv.Itoa(a.port)
413+
414+
return bprintf(patResubmitPort, p), nil
415+
}
416+
417+
// GoString implements Action.
418+
func (a *resubmitPortAction) GoString() string {
419+
return fmt.Sprintf("ovs.ResubmitPort(%d)", a.port)
420+
}
421+
388422
// MarshalText implements Action.
389423
func (a *resubmitAction) MarshalText() ([]byte, error) {
390424
if a.port == 0 && a.table == 0 {
@@ -399,10 +433,9 @@ func (a *resubmitAction) MarshalText() ([]byte, error) {
399433
t := ""
400434
if a.table != 0 {
401435
t = strconv.Itoa(a.table)
402-
return bprintf(patResubmitPortTable, p, t), nil
403436
}
404437

405-
return bprintf(patResubmitPort, p), nil
438+
return bprintf(patResubmitPortTable, p, t), nil
406439
}
407440

408441
// GoString implements Action.

ovs/action_test.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ func TestActionResubmit(t *testing.T) {
344344
{
345345
desc: "table zero",
346346
port: 1,
347-
action: "resubmit:1",
347+
action: "resubmit(1,)",
348348
},
349349
{
350350
desc: "both port and table non-zero",
@@ -374,6 +374,60 @@ func TestActionResubmit(t *testing.T) {
374374
}
375375
}
376376

377+
func TestActionResubmitPort(t *testing.T) {
378+
var tests = []struct {
379+
desc string
380+
port int
381+
action string
382+
err error
383+
}{
384+
{
385+
desc: "invalid port",
386+
port: -1,
387+
err: errResubmitPortInvalid,
388+
},
389+
{
390+
desc: "port zero",
391+
port: 0,
392+
action: "resubmit:0",
393+
},
394+
{
395+
desc: "port 1",
396+
port: 1,
397+
action: "resubmit:1",
398+
},
399+
{
400+
desc: "max port (0xfeff)",
401+
port: 0xfeff,
402+
action: "resubmit:65279",
403+
},
404+
{
405+
desc: "max port+1 (0xfeff)",
406+
port: 0xff00,
407+
err: errResubmitPortInvalid,
408+
},
409+
}
410+
411+
for _, tt := range tests {
412+
t.Run(tt.desc, func(t *testing.T) {
413+
action, err := ResubmitPort(tt.port).MarshalText()
414+
415+
if want, got := tt.err, err; want != got {
416+
t.Fatalf("unexpected error:\n- want: %v\n- got: %v",
417+
want, got)
418+
}
419+
if err != nil {
420+
return
421+
}
422+
423+
if want, got := tt.action, string(action); want != got {
424+
t.Fatalf("unexpected Action:\n- want: %q\n- got: %q",
425+
want, got)
426+
}
427+
})
428+
}
429+
}
430+
377431
func TestActionLoadSetField(t *testing.T) {
378432
var tests = []struct {
379433
desc string

ovs/actionparser.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,12 @@ func (s *stack) pop() {
145145

146146
var (
147147
// resubmitRe is the regex used to match the resubmit action
148-
// with one or more of its parameters.
149-
resubmitRe = regexp.MustCompile(`resubmit(?::(\d+)|\((\d*),(\d*)\))`)
148+
// with port and table specified
149+
resubmitRe = regexp.MustCompile(`resubmit\((\d*),(\d*)\)`)
150+
151+
// resubmitPortRe is the regex used to match the resubmit action
152+
// when only a port is specified
153+
resubmitPortRe = regexp.MustCompile(`resubmit:(\d+)`)
150154

151155
// ctRe is the regex used to match the ct action with its
152156
// parameter list.
@@ -305,8 +309,8 @@ func parseAction(s string) (Action, error) {
305309
}
306310
}
307311

308-
// ActionResubmit, with one or both of port number and table number
309-
if ss := resubmitRe.FindAllStringSubmatch(s, 1); len(ss) > 0 && len(ss[0]) == 4 {
312+
// ActionResubmit, with both port number and table number
313+
if ss := resubmitRe.FindAllStringSubmatch(s, 1); len(ss) > 0 && len(ss[0]) == 3 {
310314
var (
311315
port int
312316
table int
@@ -316,7 +320,6 @@ func parseAction(s string) (Action, error) {
316320

317321
// Results are:
318322
// - full string
319-
// - single port
320323
// - port in parenthesis
321324
// - table in parenthesis
322325

@@ -325,16 +328,8 @@ func parseAction(s string) (Action, error) {
325328
if err != nil {
326329
return nil, err
327330
}
328-
return Resubmit(port, 0), nil
329331
}
330-
331332
if s := ss[0][2]; s != "" {
332-
port, err = strconv.Atoi(s)
333-
if err != nil {
334-
return nil, err
335-
}
336-
}
337-
if s := ss[0][3]; s != "" {
338333
table, err = strconv.Atoi(s)
339334
if err != nil {
340335
return nil, err
@@ -344,6 +339,16 @@ func parseAction(s string) (Action, error) {
344339
return Resubmit(port, table), nil
345340
}
346341

342+
// ActionResubmitPort, with only a port number
343+
if ss := resubmitPortRe.FindAllStringSubmatch(s, 1); len(ss) > 0 && len(ss[0]) == 2 {
344+
port, err := strconv.Atoi(ss[0][1])
345+
if err != nil {
346+
return nil, err
347+
}
348+
349+
return ResubmitPort(port), nil
350+
}
351+
347352
if ss := loadRe.FindAllStringSubmatch(s, 2); len(ss) > 0 && len(ss[0]) == 3 {
348353
// Results are:
349354
// - full string

ovs/actionparser_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,11 @@ func Test_parseAction(t *testing.T) {
239239
},
240240
{
241241
s: "resubmit:4",
242-
a: Resubmit(4, 0),
242+
a: ResubmitPort(4),
243243
},
244244
{
245-
s: "resubmit(1,)",
246-
final: "resubmit:1",
247-
a: Resubmit(1, 0),
245+
s: "resubmit(1,)",
246+
a: Resubmit(1, 0),
248247
},
249248
{
250249
s: "resubmit(,2)",

0 commit comments

Comments
 (0)