Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions ofctrl/fgraphFlow.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ type FlowMatch struct {
UdpSrcPortMask uint16 // UDP source port mask
UdpDstPort uint16 // UDP dest port
UdpDstPortMask uint16 // UDP dest port mask
Icmp6Code *uint8 // ICMPv6 code
Icmp6Type *uint8 // ICMPv6 type
NdTarget *net.IP // ICMPv6 Neighbor Discovery Target
NdTargetMask *net.IP // Mask for ICMPv6 Neighbor Discovery Target
NdSll *net.HardwareAddr // ICMPv6 Neighbor Discovery Source Ethernet Address
NdTll *net.HardwareAddr // ICMPv6 Neighbor DIscovery Target Ethernet Address
Metadata *uint64 // OVS metadata
MetadataMask *uint64 // Metadata mask
TunnelId uint64 // Vxlan Tunnel id i.e. VNI
Expand Down Expand Up @@ -492,6 +498,35 @@ func (self *Flow) xlateMatch() openflow13.Match {
}
}

if self.Match.Icmp6Code != nil {
icmp6CodeField, _ := openflow13.FindFieldHeaderByName("NXM_NX_ICMPV6_CODE", false)
icmp6CodeField.Value = &openflow13.IcmpCodeField{Code: *self.Match.Icmp6Code}
ofMatch.AddField(*icmp6CodeField)
}
if self.Match.Icmp6Type != nil {
icmp6TypeField, _ := openflow13.FindFieldHeaderByName("NXM_NX_ICMPV6_Type", false)
icmp6TypeField.Value = &openflow13.IcmpTypeField{Type: *self.Match.Icmp6Type}
ofMatch.AddField(*icmp6TypeField)
}
if self.Match.NdTarget != nil {
ndTargetField, _ := openflow13.FindFieldHeaderByName("NXM_NX_ND_TARGET", self.Match.NdTargetMask != nil)
ndTargetField.Value = &openflow13.Ipv6DstField{Ipv6Dst: *self.Match.NdTarget}
if self.Match.NdTargetMask != nil {
ndTargetField.Mask = &openflow13.Ipv6DstField{Ipv6Dst: *self.Match.NdTargetMask}
}
ofMatch.AddField(*ndTargetField)
}
if self.Match.NdSll != nil {
ndSllField, _ := openflow13.FindFieldHeaderByName("NXM_NX_ND_SLL", false)
ndSllField.Value = &openflow13.EthSrcField{EthSrc: *self.Match.NdSll}
ofMatch.AddField(*ndSllField)
}
if self.Match.NdTll != nil {
ndTllField, _ := openflow13.FindFieldHeaderByName("NXM_NX_ND_SLL", false)
ndTllField.Value = &openflow13.EthDstField{EthDst: *self.Match.NdTll}
ofMatch.AddField(*ndTllField)
}

return *ofMatch
}

Expand Down Expand Up @@ -680,6 +715,17 @@ func (self *Flow) Next(elem FgraphElem) error {
return self.install()
}

func (self *Flow) ForceAddInstall() error {
self.lock.Lock()
defer self.lock.Unlock()

// clear installed flag
self.isInstalled = false

// Install the flow entry
return self.install()
}

func (self *Flow) SetConntrack(connTrackAction *ConnTrackAction) error {
self.flowActions = append(self.flowActions, connTrackAction)

Expand Down
18 changes: 15 additions & 3 deletions ofctrl/ofctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,18 +382,30 @@ func setDatapathID(conn *ovsdb.OvsdbClient, bridgeName string) error {
h := sha256.New()
h.Write([]byte(bridgeName))
datapathID := h.Sum(nil)[:8]
mac := net.HardwareAddr(h.Sum(nil)[:6])
mac[0] &^= 1

config, _ := ovsdb.NewOvsMap(map[string]string{"datapath-id": hex.EncodeToString(datapathID)})
operation := ovsdb.Operation{
operDpid := ovsdb.Operation{
Op: "mutate",
Table: "Bridge",
Where: []interface{}{[]interface{}{"name", "==", bridgeName}},
Mutations: []interface{}{[]interface{}{"other_config", "insert", config}}, // never update the datapath id
}
_, err := ovsdbTransact(conn, "Open_vSwitch", operation)

operMac := ovsdb.Operation{
Op: "mutate",
Table: "Port",
Where: []interface{}{[]interface{}{"name", "==", bridgeName}},
Mutations: []interface{}{[]interface{}{"mac", "insert", mac.String()}},
}
if _, err := ovsdbTransact(conn, "Open_vSwitch", operDpid, operMac); err != nil {
return err
}

log.Infof("bridge %s internal port mac (if exist) has been set to %s", bridgeName, mac.String())
log.Infof("bridge %s datapath id has been set to %s", bridgeName, hex.EncodeToString(datapathID))
return err
return nil
}

func ovsdbTransact(client *ovsdb.OvsdbClient, database string, operation ...ovsdb.Operation) ([]ovsdb.OperationResult, error) {
Expand Down
8 changes: 8 additions & 0 deletions ofctrl/ofctrl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,10 @@ func TestNewOFController(t *testing.T) {
driver := ovsdbDriver.NewOvsDriver(bridgeName)
defer driver.Delete()

if err := driver.CreatePort(bridgeName, "internal", 0); err != nil {
t.Fatalf("fail to create default internal port : %s", err)
}

_ = NewOFController(&ofActor, uint16(rand.Intn(1024)), driver.OVSClient(), bridgeName)

//wait for 2sec
Expand All @@ -871,4 +875,8 @@ func TestNewOFController(t *testing.T) {
if config["datapath-id"] == "" {
t.Fatalf("datapath id must be set before connect to switch")
}

if mac, err := driver.GetInternalPortMac(); err != nil || mac == "" {
t.Fatalf("internal port mac must be set before connect to switch, err = %s", err)
}
}
36 changes: 30 additions & 6 deletions ovsdbDriver/ovsdbDriver.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ func NewOvsDriver(bridgeName string) *OvsDriver {
_ = ovs.MonitorAll("Open_vSwitch", "")

// Create the default bridge instance
err = ovsDriver.CreateBridge(ovsDriver.OvsBridgeName)
if err != nil {
if err = ovsDriver.CreateBridge(ovsDriver.OvsBridgeName); err != nil {
log.Fatalf("Error creating the default bridge. Err: %v", err)
}

Expand Down Expand Up @@ -183,9 +182,9 @@ func (self *OvsDriver) ovsdbTransact(ops []libovsdb.Operation) error {
// Parse reply and look for errors
for i, o := range reply {
if o.Error != "" && i < len(ops) {
return errors.New("OVS Transaction failed err " + o.Error + "Details: " + o.Details)
return errors.New("OVS Transaction failed err " + o.Error + "Details: " + o.Details + " UUID: " + o.UUID.GoUuid)
} else if o.Error != "" {
return errors.New("OVS Transaction failed err " + o.Error + "Details: " + o.Details)
return errors.New("OVS Transaction failed err " + o.Error + "Details: " + o.Details + " UUID: " + o.UUID.GoUuid)
}
}

Expand Down Expand Up @@ -345,6 +344,31 @@ func (self *OvsDriver) GetOtherConfig() (map[string]string, error) {
return buildMapFromOVSDBMap(externalIds), nil
}

func (self *OvsDriver) GetInternalPortMac() (string, error) {
selectOper := libovsdb.Operation{
Op: "select",
Table: "Port",
Where: []interface{}{[]interface{}{"name", "==", self.OvsBridgeName}},
Columns: []string{"mac"},
}

opers := []libovsdb.Operation{selectOper}
ret, err := self.ovsClient.Transact("Open_vSwitch", opers...)
if err != nil {
return "", fmt.Errorf("ovsdb select internal port mac transaction failed: %v", opers)
}

if len(ret) == 0 || len(ret[0].Rows) == 0 {
return "", nil
}

mac, ok := ret[0].Rows[0]["mac"].(string)
if !ok {
return "", nil
}
return mac, nil
}

func (self *OvsDriver) SetExternalIds(externalIds map[string]string) error {
oMap := buildOVSDBMapFromMap(externalIds)
row := make(map[string]interface{})
Expand Down Expand Up @@ -406,8 +430,8 @@ func (self *OvsDriver) UpdateInterface(ifaceName string, externalIDs map[string]

// Create an internal port in OVS
func (self *OvsDriver) CreatePort(intfName, intfType string, vlanTag uint) error {
portUuidStr := intfName
intfUuidStr := fmt.Sprintf("Intf%s", intfName)
portUuidStr := "portdummy"
intfUuidStr := "ifacedummy"
portUuid := []libovsdb.UUID{{GoUuid: portUuidStr}}
intfUuid := []libovsdb.UUID{{GoUuid: intfUuidStr}}
opStr := "insert"
Expand Down