diff --git a/build/switch/main.go b/build/switch/main.go deleted file mode 100644 index aec906af66b9a0b9be1fbfbd1fc0c7e3e53957c4..0000000000000000000000000000000000000000 --- a/build/switch/main.go +++ /dev/null @@ -1,173 +0,0 @@ -package main - -import ( - "encoding/json" - "errors" - "flag" - "fmt" - "io/ioutil" - "os" - "os/exec" - "regexp" - "strings" -) - -type Node struct { - Name string `json:"name"` - NodeIP string `json:"nodeIP"` - NeighborNodes []string `json:"neighborNodes"` -} - -// Script that takes two required arguments: -// the first one is the name in the cluster of the node where the script is running -// the second one is the path to the configuration file, in reference to the code. -func main() { - - configDir, vethNumber, nodeName, controllerIP, err := takeArguments() - - if err != nil { - fmt.Println("Error with the arguments. Error:", err) - return - } - - fmt.Println("initializing switch, connected to controller: ", controllerIP) - err = initializeSwitch(controllerIP) - - if err != nil { - fmt.Println("Could not initialize switch. Error:", err) - return - } - - fmt.Println("Switch initialized and connected to the controller.") - - // Set all virtual interfaces up, and connect them to the tunnel bridge: - for i := 1; i <= vethNumber; i++ { - veth := fmt.Sprintf("net%d", i) - cmd := exec.Command("ip", "link", "set", veth, "up") // i.e: ip link set veth1 up - if err := cmd.Run(); err != nil { - fmt.Println("Error:", err) - } - exec.Command("ovs-vsctl", "add-port", "brtun", veth).Run() // i.e: ovs-vsctl add-port brtun veth1 - } - - err = createVxlans(configDir, nodeName) - - if err != nil { - fmt.Println("Vxlans not created: ", err) - return - } -} - -func takeArguments() (string, int, string, string, error) { - configDir := os.Args[len(os.Args)-1] - - vethNumber := flag.Int("n_veths", 0, "number of pod interfaces that are going to be attached to the switch") - nodeName := flag.String("node_name", "", "name of the node the script is executed in. Required.") - controllerIP := flag.String("controller_ip", "", "ip where the SDN controller is listening using the OpenFlow13 protocol. Required") - - flag.Parse() - - switch { - case *nodeName == "": - return "", 0, "", "", errors.New("Node name is not defined") - case configDir == "": - return "", 0, "", "", errors.New("Config directory is not defined") - case *controllerIP == "": - return "", 0, "", "", errors.New("Controller IP is not defined") - } - - return configDir, *vethNumber, *nodeName, *controllerIP, nil -} - -func initializeSwitch(controllerIP string) error { - - re := regexp.MustCompile(`\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b`) - if !re.MatchString(controllerIP) { - out, _ := exec.Command("host", controllerIP).Output() - controllerIP = re.FindString(string(out)) - } - - var err error - - err = exec.Command("ovs-vsctl", "add-br", "brtun").Run() - - if err != nil { - return errors.New("Could not create brtun interface") - } - - err = exec.Command("ip", "link", "set", "brtun", "up").Run() - - if err != nil { - return errors.New("Could not set brtun interface up") - } - - err = exec.Command("ovs-vsctl", "set", "bridge", "brtun", "protocols=OpenFlow13").Run() - - if err != nil { - return errors.New("Couldnt set brtun messaing protocol to OpenFlow13") - } - - target := fmt.Sprintf("tcp:%s:6633", controllerIP) - - err = exec.Command("ovs-vsctl", "set-controller", "brtun", target).Run() - - if err != nil { - return errors.New("Could not connect to controller") - } - return nil -} - -func createVxlans(configDir, nodeName string) error { - - /// Read file and save in memory the JSON info - data, err := ioutil.ReadFile(configDir) - if err != nil { - fmt.Println("No input file was found.", err) - return err - } - - var nodes []Node - err = json.Unmarshal(data, &nodes) - if err != nil { - return err - } - - // 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) - for _, neighbor := range node.NeighborNodes { - vxlanNumber := 1 - for _, n := range nodes { - if n.Name == neighbor { - neighborIP := strings.TrimSpace(n.NodeIP) - commandArgs := []string{ - "add-port", - "brtun", - fmt.Sprintf("vxlan%d", vxlanNumber), - "--", - "set", "interface", - fmt.Sprintf("vxlan%d", vxlanNumber), - "type=vxlan", - fmt.Sprintf("options:key=flow"), - fmt.Sprintf("options:remote_ip=%s", neighborIP), - fmt.Sprintf("options:local_ip=%s", nodeIP), - "options:dst_port=7000", - } - _, err := exec.Command("ovs-vsctl", commandArgs...).Output() - if err != nil { - return errors.New(fmt.Sprintf("Could not create vxlan between node %s and node %s.", node.Name, neighbor)) - } else { - fmt.Println(fmt.Sprintf("Created vxlan between node %s and node %s.", node.Name, neighbor)) - } - } - vxlanNumber++ - } - - } - } - } - return nil -} diff --git a/configs/sampleFile.json b/configs/sampleFile.json index b66ca574ad6341f61a4141ecbd1baa48e01a6d9d..a024bcf79f093c9d77cbc4f3ee783e78f48eafc9 100644 --- a/configs/sampleFile.json +++ b/configs/sampleFile.json @@ -1,12 +1,18 @@ [ { - "name": "<NODE_SWITCH_1>", - "nodeIP": "<IP_SWITCH_1>", - "neighborNodes": ["<NODE_SWITCH_2>"] + "name": "test-l2sm-uc3m-polito-1", + "nodeIP": "10.244.0.37", + "neighborNodes": ["test-l2sm-uc3m-polito-2","test-l2sm-uc3m-polito-3"] }, { - "name": "<NODE_SWITCH_2>", - "nodeIP": "<IP_SWITCH_2>", - "neighborNodes": ["<NODE_SWITCH_1>"] + "name": "test-l2sm-uc3m-polito-2", + "nodeIP": "10.244.1.64", + "neighborNodes": ["test-l2sm-uc3m-polito-1","test-l2sm-uc3m-polito-3"] + }, + { + "name": "test-l2sm-uc3m-polito-3", + "nodeIP": "10.244.2.33", + "neighborNodes": ["test-l2sm-uc3m-polito-1","test-l2sm-uc3m-polito-2"] } + ] diff --git a/build/controller/l2sm-controller-app-1.0.oar b/src/controller/l2sm-controller-app-1.0.oar similarity index 100% rename from build/controller/l2sm-controller-app-1.0.oar rename to src/controller/l2sm-controller-app-1.0.oar diff --git a/build/controller/setup_controller.sh b/src/controller/setup_controller.sh similarity index 100% rename from build/controller/setup_controller.sh rename to src/controller/setup_controller.sh diff --git a/build/operator/l2sm-operator.py b/src/operator/l2sm-operator.py similarity index 100% rename from build/operator/l2sm-operator.py rename to src/operator/l2sm-operator.py diff --git a/src/switch/cmd/l2sm-init/main.go b/src/switch/cmd/l2sm-init/main.go new file mode 100644 index 0000000000000000000000000000000000000000..30cded3a1e219327e1879dfac6e2d4dfc28015fc --- /dev/null +++ b/src/switch/cmd/l2sm-init/main.go @@ -0,0 +1,95 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "os/exec" + "regexp" +) + +// Script that takes two required arguments: +// the first one is the name in the cluster of the node where the script is running +// the second one is the path to the configuration file, in reference to the code. +func main() { + + vethNumber, controllerIP, err := takeArguments() + + if err != nil { + fmt.Println("Error with the arguments. Error:", err) + return + } + + fmt.Println("Initializing switch, connected to controller: ", controllerIP) + err = initializeSwitch(controllerIP) + + if err != nil { + fmt.Println("Could not initialize switch. Error:", err) + return + } + + fmt.Println("Switch initialized and connected to the controller.") + + // Set all virtual interfaces up, and connect them to the tunnel bridge: + for i := 1; i <= vethNumber; i++ { + veth := fmt.Sprintf("net%d", i) + cmd := exec.Command("ip", "link", "set", veth, "up") // i.e: ip link set veth1 up + if err := cmd.Run(); err != nil { + fmt.Println("Error:", err) + } + exec.Command("ovs-vsctl", "add-port", "brtun", veth).Run() // i.e: ovs-vsctl add-port brtun veth1 + } +} + +func takeArguments() (int, string, error) { + + vethNumber := flag.Int("n_veths", 0, "number of pod interfaces that are going to be attached to the switch") + controllerIP := flag.String("controller_ip", "", "ip where the SDN controller is listening using the OpenFlow13 protocol. Required") + + flag.Parse() + + switch { + case *controllerIP == "": + return 0, "", errors.New("controller IP is not defined") + } + + return *vethNumber, *controllerIP, nil +} + +func initializeSwitch(controllerIP string) error { + + re := regexp.MustCompile(`\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b`) + if !re.MatchString(controllerIP) { + out, _ := exec.Command("host", controllerIP).Output() + controllerIP = re.FindString(string(out)) + } + + var err error + + err = exec.Command("ovs-vsctl", "add-br", "brtun").Run() + + if err != nil { + return errors.New("could not create brtun interface") + } + + err = exec.Command("ip", "link", "set", "brtun", "up").Run() + + if err != nil { + return errors.New("could not set brtun interface up") + } + + err = exec.Command("ovs-vsctl", "set", "bridge", "brtun", "protocols=OpenFlow13").Run() + + if err != nil { + return errors.New("could not set brtun messaing protocol to OpenFlow13") + } + + target := fmt.Sprintf("tcp:%s:6633", controllerIP) + + err = exec.Command("ovs-vsctl", "set-controller", "brtun", target).Run() + + if err != nil { + return errors.New("could not connect to controller") + } + return nil +} diff --git a/src/switch/cmd/l2sm-vxlans/main.go b/src/switch/cmd/l2sm-vxlans/main.go new file mode 100644 index 0000000000000000000000000000000000000000..029647a90199e12bbd9a768caa388b0f96d0e04f --- /dev/null +++ b/src/switch/cmd/l2sm-vxlans/main.go @@ -0,0 +1,110 @@ +package main + +import ( + "encoding/json" + "errors" + "flag" + "fmt" + "io/ioutil" + "os" + "os/exec" + "strings" +) + +type Node struct { + Name string `json:"name"` + NodeIP string `json:"nodeIP"` + NeighborNodes []string `json:"neighborNodes"` +} + +// Script that takes two required arguments: +// the first one is the name in the cluster of the node where the script is running +// the second one is the path to the configuration file, in reference to the code. +func main() { + + configDir, nodeName, err := takeArguments() + + if err != nil { + fmt.Println("Error with the arguments. Error:", err) + return + } + + err = createVxlans(configDir, nodeName) + + if err != nil { + fmt.Println("Vxlans not created: ", err) + return + } +} + +func takeArguments() (string, string, error) { + configDir := os.Args[len(os.Args)-1] + + nodeName := flag.String("node_name", "", "name of the node the script is executed in. Required.") + + flag.Parse() + + switch { + case *nodeName == "": + return "", "", errors.New("node name is not defined") + case configDir == "": + return "", "", errors.New("config directory is not defined") + } + + return configDir, *nodeName, nil +} + +func createVxlans(configDir, nodeName string) error { + + /// Read file and save in memory the JSON info + data, err := ioutil.ReadFile(configDir) + if err != nil { + fmt.Println("No input file was found.", err) + return err + } + + var nodes []Node + err = json.Unmarshal(data, &nodes) + if err != nil { + return err + } + + // 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) + for _, neighbor := range node.NeighborNodes { + vxlanNumber := 1 + for _, n := range nodes { + if n.Name == neighbor { + neighborIP := strings.TrimSpace(n.NodeIP) + commandArgs := []string{ + "add-port", + "brtun", + fmt.Sprintf("vxlan%d", vxlanNumber), + "--", + "set", "interface", + fmt.Sprintf("vxlan%d", vxlanNumber), + "type=vxlan", + "options:key=flow", + fmt.Sprintf("options:remote_ip=%s", neighborIP), + fmt.Sprintf("options:local_ip=%s", nodeIP), + "options:dst_port=7000", + } + _, err := exec.Command("ovs-vsctl", commandArgs...).Output() + if err != nil { + return fmt.Errorf("could not create vxlan between node %s and node %s", node.Name, neighbor) + } else { + fmt.Printf("Created vxlan between node %s and node %s.\n", node.Name, neighbor) + } + } + vxlanNumber++ + } + + } + } + } + return nil +} diff --git a/build/switch/go.mod b/src/switch/go.mod similarity index 100% rename from build/switch/go.mod rename to src/switch/go.mod diff --git a/build/switch/setup_switch.sh b/src/switch/setup_switch.sh similarity index 100% rename from build/switch/setup_switch.sh rename to src/switch/setup_switch.sh