summaryrefslogtreecommitdiff
path: root/src/adapter/vyos1x_adapter.ml
blob: d4dbac710fca79123abf4e6581056fc2cb7d4430 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
open Ctypes
open Foreign

let libvyatta = Dl.dlopen ~flags:[Dl.RTLD_LAZY] ~filename:"libvyatta-cfg.so.1"

let cstore_init = foreign ~from:libvyatta "vy_cstore_init" (void @-> returning uint64_t)
let cstore_free = foreign ~from:libvyatta "vy_cstore_free" (uint64_t @-> returning void)
let in_session = foreign ~from:libvyatta "vy_in_session" (uint64_t @-> returning int)
let cstore_set_path = foreign ~from:libvyatta "vy_set_path" (uint64_t @-> (ptr void) @-> size_t @-> returning string)
let cstore_del_path = foreign ~from:libvyatta "vy_delete_path" (uint64_t @-> (ptr void) @-> size_t @-> returning string)
let cstore_validate_path = foreign ~from:libvyatta "vy_validate_path" (uint64_t @-> (ptr void) @-> size_t @-> returning string)
let cstore_legacy_set_path = foreign ~from:libvyatta "vy_legacy_set_path" (uint64_t @-> (ptr void) @-> size_t @-> returning string)

let cstore_handle_init () = Unsigned.UInt64.to_int (cstore_init ())
let cstore_handle_free h = cstore_free (Unsigned.UInt64.of_int h)
let cstore_in_config_session_handle h = in_session (Unsigned.UInt64.of_int h) = 1
let cstore_in_config_session () = cstore_in_config_session_handle (cstore_handle_init ())

let cstore_set_path handle path =
    let len = List.length path in
    let arr = CArray.of_list string path in
    cstore_set_path (Unsigned.UInt64.of_int handle) (to_voidp (CArray.start arr)) (Unsigned.Size_t.of_int len)

let legacy_validate_path handle path =
    let len = List.length path in
    let arr = CArray.of_list string path in
    cstore_validate_path (Unsigned.UInt64.of_int handle) (to_voidp (CArray.start arr)) (Unsigned.Size_t.of_int len)

let legacy_set_path handle path =
    let len = List.length path in
    let arr = CArray.of_list string path in
    cstore_legacy_set_path (Unsigned.UInt64.of_int handle) (to_voidp (CArray.start arr)) (Unsigned.Size_t.of_int len)

let cstore_delete_path handle path =
    let len = List.length path in
    let arr = CArray.of_list string path in
    cstore_del_path (Unsigned.UInt64.of_int handle) (to_voidp (CArray.start arr)) (Unsigned.Size_t.of_int len)

let set_path_reversed handle path _len =
    let path = List.rev path in
    cstore_set_path handle path

let delete_path_reversed handle path _len =
    let path = List.rev path in
    cstore_delete_path handle path

module VC = Vyconfd_client.Vyconf_client_session

let get_sockname =
    "/var/run/vyconfd.sock"

let vyconf_validate_path path =
    let socket = get_sockname in
    let token = VC.session_init socket in
    match token with
    | Error e -> Some e
    | Ok token ->
        let out = VC.session_validate_path socket token path in
        let _ = VC.session_free socket token in
        match out with
        | Ok _ -> None
        | Error e -> Some e

open Vyos1x

module CT = Config_tree
module CD = Config_diff

module ValueSet = Set.Make(String)

let add_value handle acc out v =
    let acc = v :: acc in
    out ^ (set_path_reversed handle acc (List.length acc))

let add_values handle acc out vs =
    match vs with
    | [] -> out ^ (set_path_reversed handle acc (List.length acc))
    | _ -> List.fold_left (add_value handle acc) out vs

let rec add_path handle acc out (node : CT.t) =
    let acc = (Vytree.name_of_node node) :: acc in
    let children = Vytree.children_of_node node in
    match children with
    | [] -> let data = Vytree.data_of_node node in
            let values = data.values in
            add_values handle acc out values
    | _  -> List.fold_left (add_path handle acc) out children

let del_value handle acc out v =
    let acc = v :: acc in
    out ^ (delete_path_reversed handle acc (List.length acc))

let del_values handle acc out vs =
    match vs with
    | [] -> out ^ (delete_path_reversed handle acc (List.length acc))
    | _ -> List.fold_left (del_value handle acc) out vs

let del_path handle path out =
    out ^ (cstore_delete_path handle path)

(*
let update_data (CD.Diff_cstore data) m =
    CD.Diff_cstore { data with out = m; }
*)

let cstore_diff ?recurse:_ (path : string list) (CD.Diff_cstore res) (m : CD.change) =
    let handle = res.handle in
    match m with
    | Added -> let node = Vytree.get res.right path in
               let acc = List.tl (List.rev path) in
               CD.Diff_cstore { res with out = add_path handle acc res.out node }
    | Subtracted -> CD.Diff_cstore { res with out = del_path handle path res.out }
    | Unchanged -> CD.Diff_cstore (res)
    | Updated v ->
            let ov = CT.get_values res.left path in
            let acc = List.rev path in
            match ov, v with
            | [x], [y] -> let out = del_value handle acc res.out x in
                          let out = add_value handle acc out y in
                          CD.Diff_cstore { res with out = out }
            | _, _ -> let ov_set = ValueSet.of_list ov in
                      let v_set = ValueSet.of_list v in
                      let sub_vals = ValueSet.elements (ValueSet.diff ov_set v_set) in
                      let add_vals = ValueSet.elements (ValueSet.diff v_set ov_set) in
                      let out = del_values handle acc res.out sub_vals in
                      let out = add_values handle acc out add_vals in
                      CD.Diff_cstore { res with out = out }

let load_config left right =
    let h = cstore_handle_init () in
    if not (cstore_in_config_session_handle h) then
        (cstore_handle_free h;
        let out = "not in config session\n" in
        out)
    else
        let dcstore = CD.make_diff_cstore left right h in
        let dcstore = CD.diff [] cstore_diff dcstore (Option.some left, Option.some right) in
        let ret = CD.eval_result dcstore in
        cstore_handle_free h;
        ret.out