// RegisterNode registers an agent func (self *OfnetMaster) RegisterNode(hostInfo *OfnetNode, ret *bool) error { // Create a node node := new(OfnetNode) node.HostAddr = hostInfo.HostAddr node.HostPort = hostInfo.HostPort hostKey := fmt.Sprintf("%s:%d", hostInfo.HostAddr, hostInfo.HostPort) // Add it to DB self.masterMutex.Lock() self.agentDb[hostKey] = node self.masterMutex.Unlock() log.Infof("Registered node: %+v", node) // take a read lock for accessing db self.masterMutex.RLock() defer self.masterMutex.RUnlock() // Send all existing endpoints to the new node for _, endpoint := range self.endpointDb { if node.HostAddr != endpoint.OriginatorIp.String() { var resp bool log.Infof("Sending endpoint: %+v to node %s:%d", endpoint, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.EndpointAdd", endpoint, &resp) if err != nil { log.Errorf("Error adding endpoint to %s. Err: %v", node.HostAddr, err) // continue sending other endpoints } } } // Send all existing policy rules to the new node for _, rule := range self.policyDb { var resp bool log.Infof("Sending rule: %+v to node %s:%d", rule, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("PolicyAgent.AddRule", rule, &resp) if err != nil { log.Errorf("Error adding rule to %s. Err: %v", node.HostAddr, err) // continue sending other rules } } // increment stats self.incrAgentStats(hostKey, "registered") return nil }
// Add a master // ofnet agent tries to connect to the master and download routes func (self *OfnetAgent) AddMaster(masterInfo *OfnetNode, ret *bool) error { master := new(OfnetNode) master.HostAddr = masterInfo.HostAddr master.HostPort = masterInfo.HostPort var resp bool log.Infof("Adding master: %+v", *master) masterKey := fmt.Sprintf("%s:%d", masterInfo.HostAddr, masterInfo.HostPort) // Save it in DB self.masterDb[masterKey] = master // My info to send to master myInfo := new(OfnetNode) myInfo.HostAddr = self.MyAddr myInfo.HostPort = self.MyPort // Register the agent with the master err := rpcHub.Client(master.HostAddr, master.HostPort).Call("OfnetMaster.RegisterNode", &myInfo, &resp) if err != nil { log.Fatalf("Failed to register with the master %+v. Err: %v", master, err) return err } // Perform master added callback so that datapaths can send their FDB to master err = self.datapath.MasterAdded(master) if err != nil { log.Errorf("Error making master added callback for %+v. Err: %v", master, err) } // Send all local endpoints to new master. for _, endpoint := range self.localEndpointDb { if endpoint.OriginatorIp.String() == self.localIp.String() { var resp bool log.Infof("Sending endpoint %+v to master %+v", endpoint, master) // Make the RPC call to add the endpoint to master client := rpcHub.Client(master.HostAddr, master.HostPort) err := client.Call("OfnetMaster.EndpointAdd", endpoint, &resp) if err != nil { log.Errorf("Failed to add endpoint %+v to master %+v. Err: %v", endpoint, master, err) return err } } } return nil }
// Add a master // ofnet agent tries to connect to the master and download routes func (self *OfnetAgent) AddMaster(masterInfo *OfnetNode, ret *bool) error { master := new(OfnetNode) master.HostAddr = masterInfo.HostAddr master.HostPort = masterInfo.HostPort var resp bool log.Infof("Adding master: %+v", *master) masterKey := fmt.Sprintf("%s:%d", masterInfo.HostAddr, masterInfo.HostPort) // Save it in DB self.masterDb[masterKey] = master // My info to send to master myInfo := new(OfnetNode) myInfo.HostAddr = self.MyAddr myInfo.HostPort = self.MyPort // Register the agent with the master err := rpcHub.Client(master.HostAddr, master.HostPort).Call("OfnetMaster.RegisterNode", &myInfo, &resp) if err != nil { log.Fatalf("Failed to register with the master %+v. Err: %v", master, err) return err } // Perform master added callback so that datapaths can send their FDB to master err = self.datapath.MasterAdded(master) if err != nil { log.Errorf("Error making master added callback for %+v. Err: %v", master, err) } return nil }
// AddRule adds a new rule to the policyDB func (self *OfnetMaster) AddRule(rule *OfnetPolicyRule) error { // Check if we have the rule already if self.policyDb[rule.RuleId] != nil { return errors.New("Rule already exists") } // Save the rule in DB self.policyDb[rule.RuleId] = rule // Publish it to all agents except where it came from for _, node := range self.agentDb { var resp bool log.Infof("Sending rule: %+v to node %s:%d", rule, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("PolicyAgent.AddRule", rule, &resp) if err != nil { log.Errorf("Error adding rule to %s. Err: %v", node.HostAddr, err) return err } } return nil }
// Add a mac route func (self *OfnetMaster) MacRouteAdd(macRoute *MacRoute, ret *bool) error { // Check if we have the route already and which is more recent oldRoute := self.macRouteDb[macRoute.MacAddrStr] if oldRoute != nil { // If old route has more recent timestamp, nothing to do if !macRoute.Timestamp.After(oldRoute.Timestamp) { return nil } } // Save the route in DB self.macRouteDb[macRoute.MacAddrStr] = macRoute // Publish it to all agents except where it came from for _, node := range self.agentDb { if node.HostAddr != macRoute.OriginatorIp.String() { var resp bool log.Infof("Sending MacRoute: %+v to node %s", macRoute, node.HostAddr) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("Vxlan.MacRouteAdd", macRoute, &resp) if err != nil { log.Errorf("Error adding route to %s. Err: %v", node.HostAddr, err) return err } } } *ret = true return nil }
// Delete an Endpoint func (self *OfnetMaster) EndpointDel(ep *OfnetEndpoint, ret *bool) error { // Check if we have the endpoint, if we dont have the endpoint, nothing to do oldEp := self.endpointDb[ep.EndpointID] if oldEp == nil { return nil } // If existing endpoint has more recent timestamp, nothing to do if oldEp.Timestamp.After(ep.Timestamp) { return nil } // Delete the endpoint from DB delete(self.endpointDb, ep.EndpointID) // Publish it to all agents except where it came from for _, node := range self.agentDb { if node.HostAddr != ep.OriginatorIp.String() { var resp bool log.Infof("Sending DELETE endpoint: %+v to node %s:%d", ep, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.EndpointDel", ep, &resp) if err != nil { log.Errorf("Error sending DELERE endpoint to %s. Err: %v", node.HostAddr, err) return err } } } *ret = true return nil }
// DelRule removes a rule from policy DB func (self *OfnetMaster) DelRule(rule *OfnetPolicyRule) error { // Check if we have the rule if self.policyDb[rule.RuleId] == nil { return errors.New("Rule does not exist") } // Remove the rule from DB delete(self.policyDb, rule.RuleId) // Publish it to all agents except where it came from for _, node := range self.agentDb { var resp bool log.Infof("Sending DELETE rule: %+v to node %s", rule, node.HostAddr) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("PolicyAgent.DelRule", rule, &resp) if err != nil { log.Errorf("Error adding rule to %s. Err: %v", node.HostAddr, err) return err } } return nil }
// Remove local endpoint func (self *OfnetAgent) RemoveLocalEndpoint(portNo uint32) error { // Clear it from DB delete(self.portVlanMap, portNo) epreg := self.localEndpointDb[portNo] if epreg == nil { log.Errorf("Endpoint not found for port %d", portNo) return errors.New("Endpoint not found") } // Call the datapath err := self.datapath.RemoveLocalEndpoint(*epreg) if err != nil { log.Errorf("Error deleting endpointon port %d. Err: %v", portNo, err) } // delete the endpoint from local endpoint table delete(self.endpointDb, epreg.EndpointID) // Send the DELETE to all known masters for _, master := range self.masterDb { var resp bool log.Infof("Sending DELETE endpoint %+v to master %+v", epreg, master) // Make the RPC call to delete the endpoint on master client := rpcHub.Client(master.HostAddr, master.HostPort) err := client.Call("OfnetMaster.EndpointDel", epreg, &resp) if err != nil { log.Errorf("Failed to DELETE endpoint %+v on master %+v. Err: %v", epreg, master, err) } } return nil }
// Add an Endpoint func (self *OfnetMaster) EndpointAdd(ep *OfnetEndpoint, ret *bool) error { // Check if we have the endpoint already and which is more recent oldEp := self.endpointDb[ep.EndpointID] if oldEp != nil { // If old endpoint has more recent timestamp, nothing to do if !ep.Timestamp.After(oldEp.Timestamp) { return nil } } // Save the endpoint in DB self.endpointDb[ep.EndpointID] = ep // Publish it to all agents except where it came from for _, node := range self.agentDb { if node.HostAddr != ep.OriginatorIp.String() { var resp bool log.Infof("Sending endpoint: %+v to node %s:%d", ep, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.EndpointAdd", ep, &resp) if err != nil { log.Errorf("Error adding endpoint to %s. Err: %v", node.HostAddr, err) return err } } } *ret = true return nil }
// Delete a mac route func (self *OfnetMaster) MacRouteDel(macRoute *MacRoute, ret *bool) error { // Check if we have the route, if we dont have the route, nothing to do oldRoute := self.macRouteDb[macRoute.MacAddrStr] if oldRoute == nil { return nil } // If existing route has more recent timestamp, nothing to do if oldRoute.Timestamp.After(macRoute.Timestamp) { return nil } // Delete the route from DB delete(self.macRouteDb, macRoute.MacAddrStr) // Publish it to all agents except where it came from for _, node := range self.agentDb { if node.HostAddr != macRoute.OriginatorIp.String() { var resp bool log.Infof("Sending DELETE MacRoute: %+v to node %s", macRoute, node.HostAddr) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("Vxlan.MacRouteDel", macRoute, &resp) if err != nil { log.Errorf("Error sending DELERE mac route to %s. Err: %v", node.HostAddr, err) return err } } } *ret = true return nil }
// Register an agent func (self *OfnetMaster) RegisterNode(hostInfo *OfnetNode, ret *bool) error { // Create a node node := new(OfnetNode) node.HostAddr = hostInfo.HostAddr node.HostPort = hostInfo.HostPort hostKey := fmt.Sprintf("%s:%d", hostInfo.HostAddr, hostInfo.HostPort) // Add it to DB self.agentDb[hostKey] = node log.Infof("Registered node: %+v", node) // Send all existing routes for _, route := range self.routeDb { if node.HostAddr != route.OriginatorIp.String() { var resp bool log.Infof("Sending Route: %+v to node %s", route, node.HostAddr) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("Vrouter.RouteAdd", route, &resp) if err != nil { log.Errorf("Error adding route to %s. Err: %v", node.HostAddr, err) } } } // Send all mac routes for _, macRoute := range self.macRouteDb { if node.HostAddr != macRoute.OriginatorIp.String() { var resp bool log.Infof("Sending MacRoute: %+v to node %s", macRoute, node.HostAddr) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("Vxlan.MacRouteAdd", macRoute, &resp) if err != nil { log.Errorf("Error adding route to %s. Err: %v", node.HostAddr, err) } } } return nil }
// Register an agent func (self *OfnetMaster) RegisterNode(hostInfo *OfnetNode, ret *bool) error { // Create a node node := new(OfnetNode) node.HostAddr = hostInfo.HostAddr node.HostPort = hostInfo.HostPort hostKey := fmt.Sprintf("%s:%d", hostInfo.HostAddr, hostInfo.HostPort) // Add it to DB self.agentDb[hostKey] = node log.Infof("Registered node: %+v", node) // Send all existing endpoints to the new node for _, endpoint := range self.endpointDb { if node.HostAddr != endpoint.OriginatorIp.String() { var resp bool log.Infof("Sending endpoint: %+v to node %s:%d", endpoint, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.EndpointAdd", endpoint, &resp) if err != nil { log.Errorf("Error adding endpoint to %s. Err: %v", node.HostAddr, err) } } } // Send all existing policy rules to the new node for _, rule := range self.policyDb { var resp bool log.Infof("Sending rule: %+v to node %s:%d", rule, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("PolicyAgent.AddRule", rule, &resp) if err != nil { log.Errorf("Error adding rule to %s. Err: %v", node.HostAddr, err) return err } } return nil }
// Add a local endpoint. // This takes ofp port number, mac address, vlan and IP address of the port. func (self *OfnetAgent) AddLocalEndpoint(endpoint EndpointInfo) error { // Add port vlan mapping self.portVlanMap[endpoint.PortNo] = &endpoint.Vlan // Map Vlan to VNI vni := self.vlanVniMap[endpoint.Vlan] if vni == nil { log.Errorf("VNI for vlan %d is not known", endpoint.Vlan) return errors.New("Unknown Vlan") } epId := self.getEndpointId(endpoint) // Build endpoint registry info epreg := &OfnetEndpoint{ EndpointID: epId, EndpointType: "internal", EndpointGroup: endpoint.EndpointGroup, IpAddr: endpoint.IpAddr, VrfId: 0, // FIXME set VRF correctly MacAddrStr: endpoint.MacAddr.String(), Vlan: endpoint.Vlan, Vni: *vni, OriginatorIp: self.localIp, PortNo: endpoint.PortNo, Timestamp: time.Now(), } // Call the datapath err := self.datapath.AddLocalEndpoint(*epreg) if err != nil { log.Errorf("Adding endpoint (%+v) to datapath. Err: %v", epreg, err) return err } // Add the endpoint to local routing table self.endpointDb[epId] = epreg self.localEndpointDb[endpoint.PortNo] = epreg // Send the endpoint to all known masters for _, master := range self.masterDb { var resp bool log.Infof("Sending endpoint %+v to master %+v", epreg, master) // Make the RPC call to add the endpoint to master err := rpcHub.Client(master.HostAddr, master.HostPort).Call("OfnetMaster.EndpointAdd", epreg, &resp) if err != nil { log.Errorf("Failed to add endpoint %+v to master %+v. Err: %v", epreg, master, err) return err } } return nil }
// Delete an Endpoint func (self *OfnetMaster) EndpointDel(ep *OfnetEndpoint, ret *bool) error { // Check if we have the endpoint, if we dont have the endpoint, nothing to do self.masterMutex.RLock() oldEp := self.endpointDb[ep.EndpointID] self.masterMutex.RUnlock() if oldEp == nil { log.Errorf("Received endpoint DELETE on a non existing endpoint %+v", ep) return nil } // If existing endpoint has more recent timestamp, nothing to do if oldEp.Timestamp.After(ep.Timestamp) { return nil } // Delete the endpoint from DB self.masterMutex.Lock() delete(self.endpointDb, ep.EndpointID) self.masterMutex.Unlock() // take a read lock for accessing db self.masterMutex.RLock() defer self.masterMutex.RUnlock() // Publish it to all agents except where it came from for nodeKey, node := range self.agentDb { if node.HostAddr != ep.OriginatorIp.String() { var resp bool log.Infof("Sending DELETE endpoint: %+v to node %s:%d", ep, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.EndpointDel", ep, &resp) if err != nil { log.Errorf("Error sending DELERE endpoint to %s. Err: %v", node.HostAddr, err) // Continue sending the message to other nodes // increment stats self.incrAgentStats(nodeKey, "EndpointDelFailure") } else { // increment stats self.incrAgentStats(nodeKey, "EndpointDelSent") } } } *ret = true return nil }
// Add an Endpoint func (self *OfnetMaster) EndpointAdd(ep *OfnetEndpoint, ret *bool) error { log.Infof("Received Endpoint CReate from Remote netplugin") // Check if we have the endpoint already and which is more recent self.masterMutex.RLock() oldEp := self.endpointDb[ep.EndpointID] self.masterMutex.RUnlock() if oldEp != nil { // If old endpoint has more recent timestamp, nothing to do if !ep.Timestamp.After(oldEp.Timestamp) { return nil } } // Save the endpoint in DB self.masterMutex.Lock() self.endpointDb[ep.EndpointID] = ep self.masterMutex.Unlock() // take a read lock for accessing db self.masterMutex.RLock() defer self.masterMutex.RUnlock() // Publish it to all agents except where it came from for nodeKey, node := range self.agentDb { if node.HostAddr != ep.OriginatorIp.String() { var resp bool log.Infof("Sending endpoint: %+v to node %s:%d", ep, node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.EndpointAdd", ep, &resp) if err != nil { log.Errorf("Error adding endpoint to %s. Err: %v", node.HostAddr, err) // Continue sending the message to other nodes // increment stats self.incrAgentStats(nodeKey, "EndpointAddFailure") } else { // increment stats self.incrAgentStats(nodeKey, "EndpointAddSent") } } } *ret = true return nil }
// Remove local endpoint func (self *OfnetAgent) RemoveLocalEndpoint(portNo uint32) error { // increment stats self.incrStats("RemoveLocalEndpoint") // find the local copy epreg, _ := self.localEndpointDb.Get(string(portNo)) if epreg == nil { log.Errorf("Endpoint not found for port %d", portNo) return errors.New("Endpoint not found") } ep := epreg.(*OfnetEndpoint) log.Infof("Received local endpoint remove and withdraw for {%+v}", epreg) // Call the datapath err := self.datapath.RemoveLocalEndpoint(*ep) if err != nil { log.Errorf("Error deleting endpoint port %d. Err: %v", portNo, err) } // delete the endpoint from local endpoint table self.endpointDb.Remove(ep.EndpointID) self.localEndpointDb.Remove(string(portNo)) self.portVlanMapMutex.Lock() delete(self.portVlanMap, portNo) self.portVlanMapMutex.Unlock() // Send the DELETE to all known masters self.masterDbMutex.Lock() for _, master := range self.masterDb { var resp bool log.Infof("Sending DELETE endpoint %+v to master %+v", ep, master) // Make the RPC call to delete the endpoint on master client := rpcHub.Client(master.HostAddr, master.HostPort) err := client.Call("OfnetMaster.EndpointDel", ep, &resp) if err != nil { log.Errorf("Failed to DELETE endpoint %+v on master %+v. Err: %v", epreg, master, err) } else { // increment stats self.incrStats("EndpointDelSent") } } self.masterDbMutex.Unlock() log.Infof("Local endpoint removed and withdrawn successfully") return nil }
// AddNode adds a node by calling MasterAdd rpc call on the node func (self *OfnetMaster) AddNode(hostInfo OfnetNode) error { var resp bool // my info myInfo := new(OfnetNode) myInfo.HostAddr = self.myAddr myInfo.HostPort = self.myPort client := rpcHub.Client(hostInfo.HostAddr, hostInfo.HostPort) err := client.Call("OfnetAgent.AddMaster", myInfo, &resp) if err != nil { log.Errorf("Error calling AddMaster rpc call on node %v. Err: %v", hostInfo, err) return err } return nil }
// DetachPolicy deletes policy info from policyDB - SRTE func (self *OfnetMaster) DetachPolicy(epgPolicyKey string) error { for _, node := range self.agentDb { var resp bool log.Infof("Sending detach policy: to node %s:%d", node.HostAddr, node.HostPort) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("PolicyAgent.DetachPolicy", epgPolicyKey, &resp) if err != nil { log.Errorf("Error detaching policy to %s. Err: %v", node.HostAddr, err) return err } } return nil }
// Make a dummy RPC call to all agents. for testing purposes.. func (self *OfnetMaster) MakeDummyRpcCall() error { // Call all agents for _, node := range self.agentDb { var resp bool dummyArg := "dummy string" log.Infof("Making dummy rpc call to node %+v", node) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.DummyRpc", &dummyArg, &resp) if err != nil { log.Errorf("Error making dummy rpc call to %+v. Err: %v", node, err) // Continue sending the message to other nodes } } return nil }
// Make a dummy RPC call to all agents. for testing purposes.. func (self *OfnetMaster) MakeDummyRpcCall() error { // Publish it to all agents except where it came from for _, node := range self.agentDb { var resp bool dummyArg := "dummy string" log.Infof("Making dummy rpc call to node %+v", node) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.DummyRpc", &dummyArg, &resp) if err != nil { log.Errorf("Error making dummy rpc call to %+v. Err: %v", node, err) return err } } return nil }
// Remove local endpoint func (self *Vrouter) RemoveLocalEndpoint(portNo uint32) error { // Find the route from local port number route := self.findLocalRouteByPortno(portNo) if route == nil { log.Errorf("Could not find local route ") } // Remove the port vlan flow. portVlanFlow := self.portVlanFlowDb[portNo] if portVlanFlow != nil { err := portVlanFlow.Delete() if err != nil { log.Errorf("Error deleting portvlan flow. Err: %v", err) } } // Uninstall the route err := self.uninstallRoute(route) if err != nil { log.Errorf("Error uninstalling route. Err: %v", err) } // Remove it from route table delete(self.routeTable, route.IpAddr.String()) // update timestamp so that this takes priority route.Timestamp = time.Now() // Send the route delete to all known masters for _, master := range self.agent.masterDb { var resp bool log.Infof("Sending DELETE route %+v to master %+v", route, master) // Make the RPC call to delete the route on master client := rpcHub.Client(master.HostAddr, master.HostPort) err := client.Call("OfnetMaster.RouteDel", route, &resp) if err != nil { log.Errorf("Failed to send DELETE route %+v to master %+v. Err: %v", route, master, err) } } return nil }
// Handle new master added event func (self *Vxlan) MasterAdded(master *OfnetNode) error { // Send all local routes to new master. for _, macRoute := range self.macRouteDb { if macRoute.OriginatorIp.String() == self.agent.localIp.String() { var resp bool log.Infof("Sending macRoute %+v to master %+v", macRoute, master) // Make the RPC call to add the route to master client := rpcHub.Client(master.HostAddr, master.HostPort) err := client.Call("OfnetMaster.MacRouteAdd", macRoute, &resp) if err != nil { log.Errorf("Failed to add route %+v to master %+v. Err: %v", macRoute, master, err) return err } } } return nil }
// Add a local route to routing table and distribute it func (self *Vrouter) localRouteAdd(route *OfnetRoute) error { // First, add the route to local routing table self.routeTable[route.IpAddr.String()] = route // Send the route to all known masters for _, master := range self.agent.masterDb { var resp bool log.Infof("Sending route %+v to master %+v", route, master) // Make the RPC call to add the route to master err := rpcHub.Client(master.HostAddr, master.HostPort).Call("OfnetMaster.RouteAdd", route, &resp) if err != nil { log.Errorf("Failed to add route %+v to master %+v. Err: %v", route, master, err) return err } } return nil }
// Delete a local route and inform the master func (self *Vxlan) localMacRouteDel(macRoute *MacRoute) error { // delete the route from local routing table delete(self.macRouteDb, macRoute.MacAddrStr) // Send the DELETE to all known masters for _, master := range self.agent.masterDb { var resp bool log.Infof("Sending DELETE macRoute %+v to master %+v", macRoute, master) // Make the RPC call to add the route to master client := rpcHub.Client(master.HostAddr, master.HostPort) err := client.Call("OfnetMaster.MacRouteDel", macRoute, &resp) if err != nil { log.Errorf("Failed to DELETE route %+v to master %+v. Err: %v", macRoute, master, err) return err } } return nil }
// InjectGARPs triggers GARPS in the datapath on the specified epg func (self *OfnetMaster) InjectGARPs(epgID int) { // take a read lock for accessing db self.masterMutex.RLock() defer self.masterMutex.RUnlock() // Send to all agents for nodeKey, node := range self.agentDb { var resp bool client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("OfnetAgent.InjectGARPs", epgID, &resp) if err != nil { log.Errorf("Error triggering GARP on %s. Err: %v", node.HostAddr, err) // increment stats self.incrAgentStats(nodeKey, "InjectGARPsFailure") } else { // increment stats self.incrAgentStats(nodeKey, "InjectGARPsSent") } } }
// Delete cleans up an ofnet agent func (self *OfnetAgent) Delete() error { var resp bool // Disconnect from the switch log.Infof("Received Delete for switch %s", self.ofSwitch.DPID().String) if self.GetRouterInfo() != nil { err := self.DeleteBgp() if err != nil { log.Errorf("Error clearing Bgp state,err:%s", err) return err } } if self.ofSwitch != nil { self.ofSwitch.Disconnect() } // Cleanup the controller self.ctrler.Delete() // close listeners self.rpcListener.Close() time.Sleep(100 * time.Millisecond) // My info to send to master myInfo := new(OfnetNode) myInfo.HostAddr = self.MyAddr myInfo.HostPort = self.MyPort self.masterDbMutex.Lock() defer self.masterDbMutex.Unlock() for _, node := range self.masterDb { err := rpcHub.Client(node.HostAddr, node.HostPort).Call("OfnetMaster.UnRegisterNode", &myInfo, &resp) if err != nil { log.Errorf("Failed to register with the master %+v. Err: %v", node, err) return err } } return nil }
// DelRule removes a rule from policy DB func (self *OfnetMaster) DelRule(rule *OfnetPolicyRule) error { // Check if we have the rule if self.policyDb[rule.RuleId] == nil { return errors.New("Rule does not exist") } // Remove the rule from DB self.masterMutex.Lock() delete(self.policyDb, rule.RuleId) self.masterMutex.Unlock() // take a read lock for accessing db self.masterMutex.RLock() defer self.masterMutex.RUnlock() // Publish it to all agents for nodeKey, node := range self.agentDb { var resp bool log.Infof("Sending DELETE rule: %+v to node %s", rule, node.HostAddr) client := rpcHub.Client(node.HostAddr, node.HostPort) err := client.Call("PolicyAgent.DelRule", rule, &resp) if err != nil { log.Errorf("Error adding rule to %s. Err: %v", node.HostAddr, err) // Continue sending the message to other nodes // increment stats self.incrAgentStats(nodeKey, "DelRuleFailure") } else { // increment stats self.incrAgentStats(nodeKey, "DelRuleSent") } } return nil }
// Add a local endpoint. // This takes ofp port number, mac address, vlan , VrfId and IP address of the port. func (self *OfnetAgent) AddLocalEndpoint(endpoint EndpointInfo) error { // Add port vlan mapping log.Infof("Received local endpoint add for {%+v}", endpoint) self.portVlanMapMutex.Lock() self.portVlanMap[endpoint.PortNo] = &endpoint.Vlan self.portVlanMapMutex.Unlock() // increment stats self.incrStats("AddLocalEndpoint") // Map Vlan to VNI self.vlanVniMutex.RLock() vni := self.vlanVniMap[endpoint.Vlan] self.vlanVniMutex.RUnlock() if vni == nil { log.Errorf("VNI for vlan %d is not known", endpoint.Vlan) return errors.New("Unknown Vlan") } epId := self.getEndpointIdByIpVlan(endpoint.IpAddr, endpoint.Vlan) // ignore duplicate adds if ep, _ := self.localEndpointDb.Get(string(endpoint.PortNo)); ep != nil { e := ep.(*OfnetEndpoint) if e.EndpointID == epId { return nil } } self.vlanVrfMutex.RLock() vrf := self.vlanVrf[endpoint.Vlan] self.vlanVrfMutex.RUnlock() if vrf == nil { log.Errorf("Invalid vlan to vrf mapping for %v", endpoint.Vlan) return errors.New("Invalid vlan to vrf mapping") } var v6mask net.IP if endpoint.Ipv6Addr != nil { v6mask = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") } // Build endpoint registry info epreg := &OfnetEndpoint{ EndpointID: epId, EndpointType: "internal", EndpointGroup: endpoint.EndpointGroup, IpAddr: endpoint.IpAddr, IpMask: net.ParseIP("255.255.255.255"), Ipv6Addr: endpoint.Ipv6Addr, Ipv6Mask: v6mask, Vrf: *vrf, MacAddrStr: endpoint.MacAddr.String(), Vlan: endpoint.Vlan, Vni: *vni, OriginatorIp: self.localIp, PortNo: endpoint.PortNo, Dscp: endpoint.Dscp, Timestamp: time.Now(), EndpointGroupVlan: endpoint.EndpointGroupVlan, } // Call the datapath err := self.datapath.AddLocalEndpoint(*epreg) if err != nil { log.Errorf("Adding endpoint (%+v) to datapath. Err: %v", epreg, err) return err } // Add the endpoint to local routing table self.endpointDb.Set(epId, epreg) self.localEndpointDb.Set(string(endpoint.PortNo), epreg) // Send the endpoint to all known masters self.masterDbMutex.Lock() for _, master := range self.masterDb { var resp bool log.Infof("Sending endpoint %+v to master %+v", epreg, master) // Make the RPC call to add the endpoint to master err := rpcHub.Client(master.HostAddr, master.HostPort).Call("OfnetMaster.EndpointAdd", epreg, &resp) if err != nil { log.Errorf("Failed to add endpoint %+v to master %+v. Err: %v", epreg, master, err) // Continue sending the message to other masters. } else { // increment stats self.incrStats("EndpointAddSent") } } self.masterDbMutex.Unlock() log.Infof("Local Endpoint added and distributed successfully {%+v}", epreg) return nil }
// Add a master // ofnet agent tries to connect to the master and download routes func (self *OfnetAgent) AddMaster(masterInfo *OfnetNode, ret *bool) error { master := new(OfnetNode) master.HostAddr = masterInfo.HostAddr master.HostPort = masterInfo.HostPort var resp bool log.Infof("Adding master: %+v", *master) masterKey := fmt.Sprintf("%s:%d", masterInfo.HostAddr, masterInfo.HostPort) // Save it in DB self.masterDbMutex.Lock() self.masterDb[masterKey] = master self.masterDbMutex.Unlock() // increment stats self.incrStats("MasterAdd") // My info to send to master myInfo := new(OfnetNode) myInfo.HostAddr = self.MyAddr myInfo.HostPort = self.MyPort // Register the agent with the master err := rpcHub.Client(master.HostAddr, master.HostPort).Call("OfnetMaster.RegisterNode", &myInfo, &resp) if err != nil { log.Errorf("Failed to register with the master %+v. Err: %v", master, err) // increment stats self.incrErrStats("RegisterNodeFailure") return err } // Perform master added callback so that datapaths can send their FDB to master err = self.datapath.MasterAdded(master) if err != nil { log.Errorf("Error making master added callback for %+v. Err: %v", master, err) } var ep *OfnetEndpoint // Send all local endpoints to new master. for endpoint := range self.localEndpointDb.IterBuffered() { ep = endpoint.Val.(*OfnetEndpoint) if ep.OriginatorIp.String() == self.localIp.String() { var resp bool log.Infof("Sending endpoint %+v to master %+v", ep, master) // Make the RPC call to add the endpoint to master client := rpcHub.Client(master.HostAddr, master.HostPort) err := client.Call("OfnetMaster.EndpointAdd", ep, &resp) if err != nil { log.Errorf("Failed to add endpoint %+v to master %+v. Err: %v", endpoint, master, err) // increment stats self.incrErrStats("MasterAddEndpointAddSendFailure") // continue sending other routes } else { // increment stats self.incrStats("MasterAddEndpointAddSent") } } } return nil }