Skip to content

Commit e362ab1

Browse files
committed
feat: support set flowid range in allocator
1 parent 6c489f8 commit e362ab1

File tree

3 files changed

+108
-12
lines changed

3 files changed

+108
-12
lines changed

ofctrl/cookie/allocator.go

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cookie
22

33
import (
4+
"fmt"
45
"sync"
56
)
67

@@ -10,8 +11,11 @@ const (
1011
BitWidthFlowId = 64 - BitWidthReserved - BitWidthRoundNum
1112
RoundNumMask uint64 = 0x0000_0000_f000_0000
1213
FlowIdMask uint64 = 0x0000_0000_0fff_ffff
14+
InitFlowID uint64 = 1
1315
)
1416

17+
var FlowIDExhausted error = fmt.Errorf("flow id has exhausted")
18+
1519
type ID uint64
1620

1721
func newId(round uint64, flowId uint64) ID {
@@ -31,37 +35,71 @@ func (i ID) Round() uint64 {
3135
}
3236

3337
type Allocator interface {
34-
RequestCookie() uint64
38+
RequestCookie() (uint64, error)
3539
SetFixedMask(uint64)
3640
}
3741

42+
type AllocatorOption func(*allocator) error
43+
3844
type allocator struct {
3945
roundNum uint64
4046
flowID uint64
4147
fixedMask uint64
4248
flowIDLock sync.RWMutex
49+
maxFlowID uint64
4350
}
4451

4552
// cookie will 'OR' fixed mask
4653
func (a *allocator) SetFixedMask(mask uint64) {
4754
a.fixedMask = mask
4855
}
4956

50-
func (a *allocator) RequestCookie() uint64 {
57+
func (a *allocator) RequestCookie() (uint64, error) {
5158
a.flowIDLock.Lock()
5259
defer a.flowIDLock.Unlock()
5360

61+
if a.maxFlowID != 0 && a.flowID > a.maxFlowID {
62+
return 0, FlowIDExhausted
63+
}
5464
rawID := newId(a.roundNum, a.flowID).RawId()
5565
a.flowID += 1
56-
return rawID | a.fixedMask
66+
return rawID | a.fixedMask, nil
67+
}
68+
69+
func (a *allocator) setFlowIDRange(start, end uint64) error {
70+
if start > end {
71+
return fmt.Errorf("param error, start %x can't bigger than end %x", start, end)
72+
}
73+
maxFlowIDOrigin := uint64(1<<BitWidthFlowId - 1)
74+
minFlowID := InitFlowID
75+
if start < minFlowID {
76+
return fmt.Errorf("start %x can't small than minFlowID %x", start, minFlowID)
77+
}
78+
if end > maxFlowIDOrigin {
79+
return fmt.Errorf("end %x can't biggger than maxFlowID %x", end, maxFlowIDOrigin)
80+
}
81+
a.flowID = start
82+
a.maxFlowID = end
83+
return nil
84+
}
85+
86+
func SetFlowIDRange(start, end uint64) AllocatorOption {
87+
return func(a *allocator) error {
88+
return a.setFlowIDRange(start, end)
89+
}
5790
}
5891

59-
func NewAllocator(roundNum uint64) Allocator {
92+
func NewAllocator(roundNum uint64, options ...AllocatorOption) Allocator {
6093
a := &allocator{
6194
roundNum: roundNum,
62-
flowID: 1,
95+
flowID: InitFlowID,
6396
flowIDLock: sync.RWMutex{},
6497
}
98+
for _, o := range options {
99+
if err := o(a); err != nil {
100+
return nil
101+
}
102+
}
65103
return a
66104
}
67105

ofctrl/cookie/allocator_test.go

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,93 @@ import (
77
func TestAllocateCookie(t *testing.T) {
88
allocator := NewAllocator(0)
99

10-
cookie := allocator.RequestCookie()
10+
cookie, err := allocator.RequestCookie()
11+
if err != nil {
12+
t.Errorf("unexpectd return err %s", err)
13+
}
1114
if cookie != 0x1 {
1215
t.Errorf("request cookie fail, expect 0x1, got %x", cookie)
1316
}
1417

15-
cookie = allocator.RequestCookie()
18+
cookie, err = allocator.RequestCookie()
19+
if err != nil {
20+
t.Errorf("unexpectd return err %s", err)
21+
}
1622
if cookie != 0x2 {
1723
t.Errorf("request cookie fail, expect 0x2, got %x", cookie)
1824
}
1925

2026
allocator.SetFixedMask(0x10)
2127

22-
cookie = allocator.RequestCookie()
28+
cookie, err = allocator.RequestCookie()
29+
if err != nil {
30+
t.Errorf("unexpectd return err %s", err)
31+
}
2332
if cookie != 0x13 {
2433
t.Errorf("request cookie fail, expect 0x13, got %x", cookie)
2534
}
2635

2736
allocator = NewAllocator(1)
2837

29-
cookie = allocator.RequestCookie()
38+
cookie, err = allocator.RequestCookie()
39+
if err != nil {
40+
t.Errorf("unexpectd return err %s", err)
41+
}
3042
if cookie != 0x10000001 {
3143
t.Errorf("request cookie fail, expect 0x10000001, got %x", cookie)
3244
}
3345

34-
cookie = allocator.RequestCookie()
46+
cookie, err = allocator.RequestCookie()
47+
if err != nil {
48+
t.Errorf("unexpectd return err %s", err)
49+
}
3550
if cookie != 0x10000002 {
3651
t.Errorf("request cookie fail, expect 0x10000002, got %x", cookie)
3752
}
3853

3954
allocator.SetFixedMask(0x100000000)
4055

41-
cookie = allocator.RequestCookie()
56+
cookie, err = allocator.RequestCookie()
57+
if err != nil {
58+
t.Errorf("unexpectd return err %s", err)
59+
}
4260
if cookie != 0x110000003 {
4361
t.Errorf("request cookie fail, expect 0x110000003, got %x", cookie)
4462
}
63+
64+
allocator = NewAllocator(1, SetFlowIDRange(10, 9))
65+
if allocator != nil {
66+
t.Errorf("expect allocator is nil, but real is not")
67+
}
68+
69+
allocator = NewAllocator(1, SetFlowIDRange(0, 9))
70+
if allocator != nil {
71+
t.Errorf("expect allocator is nil, but real is not")
72+
}
73+
74+
allocator = NewAllocator(1, SetFlowIDRange(10, 1<<BitWidthFlowId))
75+
if allocator != nil {
76+
t.Errorf("expect allocator is nil, but real is not")
77+
}
78+
79+
allocator = NewAllocator(1, SetFlowIDRange(10, 11))
80+
81+
cookie, err = allocator.RequestCookie()
82+
if err != nil {
83+
t.Errorf("unexpectd return err %s", err)
84+
}
85+
if cookie != 0x1000000a {
86+
t.Errorf("request cookie fail, expect 0x1000000a , got %x", cookie)
87+
}
88+
cookie, err = allocator.RequestCookie()
89+
if err != nil {
90+
t.Errorf("unexpectd return err %s", err)
91+
}
92+
if cookie != 0x1000000b {
93+
t.Errorf("request cookie fail, expect 0x1000000b, got %x", cookie)
94+
}
95+
cookie, err = allocator.RequestCookie()
96+
if err == nil {
97+
t.Errorf("expect allocate cookie failed, but success")
98+
}
4599
}

ofctrl/fgraphTable.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ func (self *Table) NewFlow(match FlowMatch) (*Flow, error) {
5454
return nil, dperror.NewDpError(dperror.SwitchDisconnectedError.Code, dperror.SwitchDisconnectedError.Msg, fmt.Errorf("ofSwitch disconnected"))
5555
}
5656
if self.Switch.CookieAllocator != nil {
57-
flow.FlowID = self.Switch.CookieAllocator.RequestCookie()
57+
var err error
58+
flow.FlowID, err = self.Switch.CookieAllocator.RequestCookie()
59+
if err != nil {
60+
return nil, err
61+
}
5862
} else {
5963
flow.FlowID = globalFlowID // FIXME: need a better id allocation
6064
globalFlowID += 1

0 commit comments

Comments
 (0)