b50444073a11a5101a261326eb6e6067181531ae
[ovn4nfv-k8s-plugin.git] / internal / pkg / ovn / common.go
1 package ovn
2
3 import (
4         "encoding/json"
5         "fmt"
6         "github.com/sirupsen/logrus"
7         "math/big"
8         "math/rand"
9         "net"
10         "time"
11 )
12
13 func SetupDistributedRouter(name string) error {
14
15         // Make sure br-int is created.
16         stdout, stderr, err := RunOVSVsctlUnix("--", "--may-exist", "add-br", "br-int")
17         if err != nil {
18                 logrus.Errorf("Failed to create br-int, stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
19                 return err
20         }
21         // Create a single common distributed router for the cluster.
22         stdout, stderr, err = RunOVNNbctlUnix("--", "--may-exist", "lr-add", name, "--", "set", "logical_router", name, "external_ids:ovn4nfv-cluster-router=yes")
23         if err != nil {
24                 logrus.Errorf("Failed to create a single common distributed router for the cluster, stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
25                 return err
26         }
27         // Create a logical switch called "ovn4nfv-join" that will be used to connect gateway routers to the distributed router.
28         // The "ovn4nfv-join" will be allocated IP addresses in the range 100.64.1.0/24.
29         stdout, stderr, err = RunOVNNbctlUnix("--may-exist", "ls-add", "ovn4nfv-join")
30         if err != nil {
31                 logrus.Errorf("Failed to create logical switch called \"ovn4nfv-join\", stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
32                 return err
33         }
34         // Connect the distributed router to "ovn4nfv-join".
35         routerMac, stderr, err := RunOVNNbctlUnix("--if-exist", "get", "logical_router_port", "rtoj-"+name, "mac")
36         if err != nil {
37                 logrus.Errorf("Failed to get logical router port rtoj-%v, stderr: %q, error: %v", name, stderr, err)
38                 return err
39         }
40         if routerMac == "" {
41                 routerMac = generateMac()
42                 stdout, stderr, err = RunOVNNbctlUnix("--", "--may-exist", "lrp-add", name, "rtoj-"+name, routerMac, "100.64.1.1/24", "--", "set", "logical_router_port", "rtoj-"+name, "external_ids:connect_to_ovn4nfvjoin=yes")
43                 if err != nil {
44                         logrus.Errorf("Failed to add logical router port rtoj-%v, stdout: %q, stderr: %q, error: %v", name, stdout, stderr, err)
45                         return err
46                 }
47         }
48         // Connect the switch "ovn4nfv-join" to the router.
49         stdout, stderr, err = RunOVNNbctlUnix("--", "--may-exist", "lsp-add", "ovn4nfv-join", "jtor-"+name, "--", "set", "logical_switch_port", "jtor-"+name, "type=router", "options:router-port=rtoj-"+name, "addresses="+"\""+routerMac+"\"")
50         if err != nil {
51                 logrus.Errorf("Failed to add logical switch port to logical router, stdout: %q, stderr: %q, error: %v", stdout, stderr, err)
52                 return err
53         }
54         return nil
55 }
56
57 func parseOvnNetworkObject(ovnnetwork string) ([]map[string]interface{}, error) {
58         var ovnNet []map[string]interface{}
59
60         if ovnnetwork == "" {
61                 return nil, fmt.Errorf("parseOvnNetworkObject:error")
62         }
63
64         if err := json.Unmarshal([]byte(ovnnetwork), &ovnNet); err != nil {
65                 return nil, fmt.Errorf("parseOvnNetworkObject: failed to load ovn network err: %v | ovn network: %v", err, ovnnetwork)
66         }
67
68         return ovnNet, nil
69 }
70
71 // generateMac generates mac address.
72 func generateMac() string {
73         prefix := "00:00:00"
74         newRand := rand.New(rand.NewSource(time.Now().UnixNano()))
75         mac := fmt.Sprintf("%s:%02x:%02x:%02x", prefix, newRand.Intn(255), newRand.Intn(255), newRand.Intn(255))
76         return mac
77 }
78
79 // NextIP returns IP incremented by 1
80 func NextIP(ip net.IP) net.IP {
81         i := ipToInt(ip)
82         return intToIP(i.Add(i, big.NewInt(1)))
83 }
84
85 func ipToInt(ip net.IP) *big.Int {
86         if v := ip.To4(); v != nil {
87                 return big.NewInt(0).SetBytes(v)
88         }
89         return big.NewInt(0).SetBytes(ip.To16())
90 }
91
92 func intToIP(i *big.Int) net.IP {
93         return net.IP(i.Bytes())
94 }