|
45 | 45 | // errResubmitPortInvalid is returned when ResubmitPort is given a port number that is |
46 | 46 | // invalid per the openflow spec. |
47 | 47 | errResubmitPortInvalid = errors.New("resubmit port must be between 0 and 65279 inclusive") |
| 48 | + |
| 49 | + // errTooManyDimensions is returned when the specified dimension exceeds the total dimension |
| 50 | + // in a conjunction action. |
| 51 | + errDimensionTooLarge = errors.New("dimension number exceeds total number of dimensions") |
48 | 52 | ) |
49 | 53 |
|
50 | 54 | // Action strings in lower case, as those are compared to the lower case letters |
@@ -145,6 +149,7 @@ func StripVLAN() Action { |
145 | 149 | // printf-style patterns for marshaling and unmarshaling actions. |
146 | 150 | const ( |
147 | 151 | patConnectionTracking = "ct(%s)" |
| 152 | + patConjunction = "conjunction(%d, %d/%d)" |
148 | 153 | patModDataLinkDestination = "mod_dl_dst:%s" |
149 | 154 | patModDataLinkSource = "mod_dl_src:%s" |
150 | 155 | patModNetworkDestination = "mod_nw_dst:%s" |
@@ -372,6 +377,37 @@ func (a *outputAction) GoString() string { |
372 | 377 | return fmt.Sprintf("ovs.Output(%d)", a.port) |
373 | 378 | } |
374 | 379 |
|
| 380 | +// Conjunction associates a flow with a certain conjunction ID to match on more than |
| 381 | +// one dimension across multiple set matches. |
| 382 | +func Conjunction(id int, dimensionNumber int, dimensionSize int) Action { |
| 383 | + return &conjunctionAction{ |
| 384 | + id: id, |
| 385 | + dimensionNumber: dimensionNumber, |
| 386 | + dimensionSize: dimensionSize, |
| 387 | + } |
| 388 | +} |
| 389 | + |
| 390 | +// A conjuctionAction is an Action which is used by Conjunction. |
| 391 | +type conjunctionAction struct { |
| 392 | + id int |
| 393 | + dimensionNumber int |
| 394 | + dimensionSize int |
| 395 | +} |
| 396 | + |
| 397 | +// MarshalText implements Action. |
| 398 | +func (a *conjunctionAction) MarshalText() ([]byte, error) { |
| 399 | + if a.dimensionNumber > a.dimensionSize { |
| 400 | + return nil, errDimensionTooLarge |
| 401 | + } |
| 402 | + |
| 403 | + return bprintf(patConjunction, a.id, a.dimensionNumber, a.dimensionSize), nil |
| 404 | +} |
| 405 | + |
| 406 | +// GoString implements Action. |
| 407 | +func (a *conjunctionAction) GoString() string { |
| 408 | + return fmt.Sprintf("ovs.Conjunction(%d, %d, %d)", a.id, a.dimensionNumber, a.dimensionSize) |
| 409 | +} |
| 410 | + |
375 | 411 | // Resubmit resubmits a packet for further processing by matching |
376 | 412 | // flows with the specified port and table. If port or table are zero, |
377 | 413 | // they are set to empty in the output Action. If both are zero, an |
|
0 commit comments