From c8d5124a818a9b45b4a5be7f7de68f42455e0331 Mon Sep 17 00:00:00 2001 From: Alex ubuntu vm <alexdecb@yahoo.es> Date: Mon, 22 Apr 2024 15:33:32 +0200 Subject: [PATCH] switches: restructured the file that defines the topology --- configs/networkTopology.json | 8 ++ configs/sampleFile.json | 12 +-- configs/switchConfig.json | 8 ++ src/switch/cmd/l2sm-vxlans/main.go | 133 +++++++++++++++++++++++------ 4 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 configs/networkTopology.json create mode 100644 configs/switchConfig.json diff --git a/configs/networkTopology.json b/configs/networkTopology.json new file mode 100644 index 0000000..f9088bf --- /dev/null +++ b/configs/networkTopology.json @@ -0,0 +1,8 @@ +{ + "Nodes": [ + {"name": "l2sm1", "nodeIP": "10.1.14.29"},{"name": "l2sm2", "nodeIP": "10.1.72.109"} + ], + "Links": [ + {"endpointA": "l2sm1", "endpointB": "l2sm2"} + ] +} diff --git a/configs/sampleFile.json b/configs/sampleFile.json index b66ca57..8f6038a 100644 --- a/configs/sampleFile.json +++ b/configs/sampleFile.json @@ -1,12 +1,12 @@ [ { - "name": "<NODE_SWITCH_1>", - "nodeIP": "<IP_SWITCH_1>", - "neighborNodes": ["<NODE_SWITCH_2>"] + "name": "l2sm1", + "nodeIP": "10.1.14.34", + "neighborNodes": ["l2sm2"] }, { - "name": "<NODE_SWITCH_2>", - "nodeIP": "<IP_SWITCH_2>", - "neighborNodes": ["<NODE_SWITCH_1>"] + "name": "l2sm2", + "nodeIP": "10.1.72.84", + "neighborNodes": ["l2sm1"] } ] diff --git a/configs/switchConfig.json b/configs/switchConfig.json new file mode 100644 index 0000000..f9088bf --- /dev/null +++ b/configs/switchConfig.json @@ -0,0 +1,8 @@ +{ + "Nodes": [ + {"name": "l2sm1", "nodeIP": "10.1.14.29"},{"name": "l2sm2", "nodeIP": "10.1.72.109"} + ], + "Links": [ + {"endpointA": "l2sm1", "endpointB": "l2sm2"} + ] +} diff --git a/src/switch/cmd/l2sm-vxlans/main.go b/src/switch/cmd/l2sm-vxlans/main.go index 3c3434d..7573f78 100644 --- a/src/switch/cmd/l2sm-vxlans/main.go +++ b/src/switch/cmd/l2sm-vxlans/main.go @@ -5,15 +5,24 @@ import ( "errors" "flag" "fmt" - "io/ioutil" "os" "ovs-switch/pkg/ovs" ) type Node struct { - Name string `json:"name"` - NodeIP string `json:"nodeIP"` - NeighborNodes []Node `json:"neighborNodes"` + Name string `json:"name"` + NodeIP string `json:"nodeIP"` + NeighborNodes []string `json:"neighborNodes"` +} + +type Link struct { + EndpointNodeA string `json:"endpointA"` + EndpointNodeB string `json:"endpointB"` +} + +type Topology struct { + Nodes []Node `json:"Nodes"` + Links []Link `json:"Links"` } // Script that takes two required arguments: @@ -21,6 +30,8 @@ type Node struct { // the second one is the path to the configuration file, in reference to the code. func main() { + //configDir, _, fileType, err := takeArguments() + configDir, nodeName, fileType, err := takeArguments() bridge := ovs.FromName("brtun") @@ -30,14 +41,30 @@ func main() { return } - nodes, err := readFile(configDir) - switch fileType { case "topology": - err = createTopology(bridge, nodes, nodeName) + var topology Topology + + err = readFile(configDir, &topology) + + if err != nil { + fmt.Println("Error with the provided file. Error:", err) + return + } + + fmt.Println(topology) + err = createTopology(bridge, topology, nodeName) case "neighbors": - err = connectToNeighbors(bridge, nodes[0]) + var node Node + err := readFile(configDir, &node) + + if err != nil { + fmt.Println("Error with the provided file. Error:", err) + return + } + + err = connectToNeighbors(bridge, node) } if err != nil { @@ -58,7 +85,7 @@ func takeArguments() (string, string, string, error) { switch { case *nodeName == "": return "", "", "", errors.New("node name is not defined") - case *fileType != "topology" || *fileType != "neighbors": + case *fileType != "topology" && *fileType != "neighbors": return "", "", "", errors.New("file type not supported. Available types: 'topology' and 'neighbors'") case configDir == "": return "", "", "", errors.New("config directory is not defined") @@ -67,47 +94,97 @@ func takeArguments() (string, string, string, error) { return configDir, *nodeName, *fileType, nil } -func createTopology(bridge ovs.Bridge, nodes []Node, nodeName string) error { +/** +Example: +{ + "Nodes": [ + { + "name": "l2sm1", + "nodeIP": "10.1.14.53" + }, + { + "name": "l2sm2", + "nodeIP": "10.1.14.90" + } + ], + "Links": [ + { + "endpointA": "l2sm1", + "endpointB": "l2sm2" + } + ] +} - // Search for the corresponding node in the configuration, according to the first passed parameter. - // Once the node is found, create a bridge for every neighbour node defined. - // The bridge is created with the nodeIp and neighborNodeIP and VNI. The VNI is generated in the l2sm-controller thats why its set to 'flow'. - for _, node := range nodes { - if node.Name == nodeName { - //nodeIP := strings.TrimSpace(node.NodeIP) - connectToNeighbors(bridge, node) +*/ +func createTopology(bridge ovs.Bridge, topology Topology, nodeName string) error { + + nodeMap := make(map[string]string) + for _, node := range topology.Nodes { + nodeMap[node.Name] = node.NodeIP + } + + localIp := nodeMap[nodeName] + + for vxlanNumber, link := range topology.Links { + vxlanId := fmt.Sprintf("vxlan%d", vxlanNumber) + var remoteIp string + switch nodeName { + case link.EndpointNodeA: + remoteIp = nodeMap[link.EndpointNodeB] + case link.EndpointNodeB: + remoteIp = nodeMap[link.EndpointNodeA] + default: + break } + err := bridge.CreateVxlan(ovs.Vxlan{VxlanId: vxlanId, LocalIp: localIp, RemoteIp: remoteIp, UdpPort: "7000"}) + + if err != nil { + return fmt.Errorf("could not create vxlan between node %s and node %s", link.EndpointNodeA, link.EndpointNodeB) + } else { + fmt.Printf("Created vxlan between node %s and node %s.\n", link.EndpointNodeA, link.EndpointNodeB) + } + } return nil + } -func readFile(configDir string) ([]Node, error) { +func readFile(configDir string, dataStruct interface{}) error { + /// Read file and save in memory the JSON info - data, err := ioutil.ReadFile(configDir) + data, err := os.ReadFile(configDir) if err != nil { fmt.Println("No input file was found.", err) - return nil, err + return err } - var nodes []Node - err = json.Unmarshal(data, &nodes) + err = json.Unmarshal(data, &dataStruct) if err != nil { - return nil, err + return err } - return nodes, nil + return nil } +/** +Example: + + { + "Name": "l2sm1", + "nodeIP": "10.1.14.53", + "neighborNodes":["10.4.2.3","10.4.2.5"] + } +*/ func connectToNeighbors(bridge ovs.Bridge, node Node) error { - for vxlanNumber, neighbor := range node.NeighborNodes { + for vxlanNumber, neighborIp := range node.NeighborNodes { vxlanId := fmt.Sprintf("vxlan%d", vxlanNumber) - err := bridge.CreateVxlan(ovs.Vxlan{VxlanId: vxlanId, LocalIp: node.NodeIP, RemoteIp: neighbor.NodeIP, UdpPort: "7000"}) + err := bridge.CreateVxlan(ovs.Vxlan{VxlanId: vxlanId, LocalIp: node.NodeIP, RemoteIp: neighborIp, UdpPort: "7000"}) if err != nil { - return fmt.Errorf("could not create vxlan between node %s and node %s", node.Name, neighbor) + return fmt.Errorf("could not create vxlan with neighbor %s", neighborIp) } else { - fmt.Printf("Created vxlan between node %s and node %s.\n", node.Name, neighbor) + fmt.Printf("Created vxlan with neighbor %s", neighborIp) } } return nil -- GitLab