VOM: mprefix and mpath encode fixes
[vpp.git] / extras / vom / vom / route_api_types.cpp
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vom/route.hpp>
17 #include <vom/route_api_types.hpp>
18
19 namespace VOM {
20
21 void
22 to_vpp(const route::path& p, vapi_payload_ip_add_del_route& payload)
23 {
24   payload.is_drop = 0;
25   payload.is_unreach = 0;
26   payload.is_prohibit = 0;
27   payload.is_local = 0;
28   payload.is_classify = 0;
29   payload.is_multipath = 0;
30   payload.is_resolve_host = 0;
31   payload.is_resolve_attached = 0;
32
33   if (route::path::flags_t::DVR & p.flags()) {
34     payload.is_dvr = 1;
35   }
36
37   if (route::path::special_t::STANDARD == p.type()) {
38     uint8_t path_v6;
39     to_bytes(p.nh(), &path_v6, payload.next_hop_address);
40
41     if (p.rd()) {
42       payload.next_hop_table_id = p.rd()->table_id();
43     }
44     if (p.itf()) {
45       payload.next_hop_sw_if_index = p.itf()->handle().value();
46     }
47   } else if (route::path::special_t::DROP == p.type()) {
48     payload.is_drop = 1;
49   } else if (route::path::special_t::UNREACH == p.type()) {
50     payload.is_unreach = 1;
51   } else if (route::path::special_t::PROHIBIT == p.type()) {
52     payload.is_prohibit = 1;
53   } else if (route::path::special_t::LOCAL == p.type()) {
54     payload.is_local = 1;
55   }
56   payload.next_hop_weight = p.weight();
57   payload.next_hop_preference = p.preference();
58   payload.next_hop_via_label = 0;
59   payload.classify_table_index = 0;
60 }
61
62 void
63 to_vpp(const route::path& p, vapi_payload_ip_mroute_add_del& payload)
64 {
65   payload.next_hop_afi = p.nh_proto();
66
67   if (route::path::special_t::STANDARD == p.type()) {
68     uint8_t path_v6;
69     to_bytes(p.nh(), &path_v6, payload.nh_address);
70
71     if (p.itf()) {
72       payload.next_hop_sw_if_index = p.itf()->handle().value();
73     }
74
75     payload.next_hop_afi = p.nh_proto();
76   } else if (route::path::special_t::LOCAL == p.type()) {
77     payload.is_local = 1;
78   }
79 }
80
81 route::path
82 from_vpp(const vapi_type_fib_path& p, const nh_proto_t& nhp)
83 {
84   if (p.is_local) {
85     return route::path(route::path::special_t::LOCAL);
86   } else if (p.is_drop) {
87     return route::path(route::path::special_t::DROP);
88   } else if (p.is_unreach) {
89     return route::path(route::path::special_t::UNREACH);
90   } else if (p.is_prohibit) {
91     return route::path(route::path::special_t::PROHIBIT);
92   } else {
93     boost::asio::ip::address address =
94       from_bytes(nh_proto_t::IPV6 == nhp, p.next_hop);
95     std::shared_ptr<interface> itf = interface::find(p.sw_if_index);
96     if (itf) {
97       if (p.is_dvr) {
98         return route::path(*itf, nhp, route::path::flags_t::DVR, p.weight,
99                            p.preference);
100       } else {
101         return route::path(address, *itf, p.weight, p.preference);
102       }
103     } else {
104       std::shared_ptr<route_domain> rd = route_domain::find(p.table_id);
105       if (rd) {
106         return route::path(*rd, address, p.weight, p.preference);
107       }
108     }
109   }
110
111   VOM_LOG(log_level_t::ERROR) << "cannot decode: ";
112
113   return route::path(route::path::special_t::DROP);
114 }
115 };
116
117 /*
118  * fd.io coding-style-patch-verification: ON
119  *
120  * Local Variables:
121  * eval: (c-set-style "mozilla")
122  * End:
123  */