diff --git a/ofctrl/cookie/allocator.go b/ofctrl/cookie/allocator.go index f3f43101..46527b4d 100644 --- a/ofctrl/cookie/allocator.go +++ b/ofctrl/cookie/allocator.go @@ -1,6 +1,7 @@ package cookie import ( + "fmt" "sync" ) @@ -10,8 +11,11 @@ const ( BitWidthFlowId = 64 - BitWidthReserved - BitWidthRoundNum RoundNumMask uint64 = 0x0000_0000_f000_0000 FlowIdMask uint64 = 0x0000_0000_0fff_ffff + InitFlowID uint64 = 1 ) +var FlowIDExhausted error = fmt.Errorf("flow id has exhausted") + type ID uint64 func newId(round uint64, flowId uint64) ID { @@ -31,15 +35,18 @@ func (i ID) Round() uint64 { } type Allocator interface { - RequestCookie() uint64 + RequestCookie() (uint64, error) SetFixedMask(uint64) } +type AllocatorOption func(*allocator) error + type allocator struct { roundNum uint64 flowID uint64 fixedMask uint64 flowIDLock sync.RWMutex + maxFlowID uint64 } // cookie will 'OR' fixed mask @@ -47,21 +54,63 @@ func (a *allocator) SetFixedMask(mask uint64) { a.fixedMask = mask } -func (a *allocator) RequestCookie() uint64 { +func (a *allocator) RequestCookie() (uint64, error) { a.flowIDLock.Lock() defer a.flowIDLock.Unlock() + if a.maxFlowID != 0 && a.flowID > a.maxFlowID { + return 0, FlowIDExhausted + } rawID := newId(a.roundNum, a.flowID).RawId() a.flowID += 1 - return rawID | a.fixedMask + return rawID | a.fixedMask, nil } -func NewAllocator(roundNum uint64) Allocator { +func (a *allocator) setFlowIDRange(start, end uint64) error { + if start > end { + return fmt.Errorf("param error, start %x can't bigger than end %x", start, end) + } + maxFlowIDOrigin := uint64(1< maxFlowIDOrigin { + return fmt.Errorf("end %x can't biggger than maxFlowID %x", end, maxFlowIDOrigin) + } + a.flowID = start + a.maxFlowID = end + return nil +} + +func (a *allocator) setDefaultFlowIDRange() { + a.flowID = InitFlowID + a.maxFlowID = uint64(1<vlan_vid,goto_table:1") { - t.Errorf("in port flow still found in OVS after deleting it.") - } - - // match ip flow - if ofctlFlowMatch(flowList, 1, "priority=100,ip,nw_dst=10.10.10.10", - "output:1") { - t.Errorf("IP flow not found in OVS.") - } - - // match mac flow - if ofctlFlowMatch(flowList, 1, "priority=100,dl_vlan=1,dl_dst=02:01:01:01:01:01", - "pop_vlan,output:1") { - t.Errorf("Mac flow not found in OVS.") - } - - // match tcp flow - if ofctlFlowMatch(flowList, 1, "priority=100,tcp,tp_dst=80,tcp_flags=+syn", - "output:1") { - t.Errorf("IP flow not found in OVS.") + if len(flowList) != 0 { + t.Errorf("doesn't delete all flow: %s", flowList) } }