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
|
/*
* Copyright (c) 2018 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vom/route.hpp>
#include <vom/route_api_types.hpp>
namespace VOM {
void
to_vpp(const route::path& p, vapi_payload_ip_add_del_route& payload)
{
payload.is_drop = 0;
payload.is_unreach = 0;
payload.is_prohibit = 0;
payload.is_local = 0;
payload.is_classify = 0;
payload.is_resolve_host = 0;
payload.is_resolve_attached = 0;
if (route::path::flags_t::DVR & p.flags()) {
payload.is_dvr = 1;
}
if (route::path::special_t::STANDARD == p.type()) {
uint8_t path_v6;
to_bytes(p.nh(), &path_v6, payload.next_hop_address);
payload.next_hop_sw_if_index = 0xffffffff;
if (p.rd()) {
payload.next_hop_table_id = p.rd()->table_id();
}
if (p.itf()) {
payload.next_hop_sw_if_index = p.itf()->handle().value();
}
} else if (route::path::special_t::DROP == p.type()) {
payload.is_drop = 1;
} else if (route::path::special_t::UNREACH == p.type()) {
payload.is_unreach = 1;
} else if (route::path::special_t::PROHIBIT == p.type()) {
payload.is_prohibit = 1;
} else if (route::path::special_t::LOCAL == p.type()) {
payload.is_local = 1;
}
payload.next_hop_weight = p.weight();
payload.next_hop_preference = p.preference();
payload.next_hop_via_label = 0x100000;
payload.classify_table_index = 0;
}
void
to_vpp(const route::path& p, vapi_payload_ip_mroute_add_del& payload)
{
payload.next_hop_afi = p.nh_proto();
if (route::path::special_t::STANDARD == p.type()) {
uint8_t path_v6;
to_bytes(p.nh(), &path_v6, payload.nh_address);
if (p.itf()) {
payload.next_hop_sw_if_index = p.itf()->handle().value();
}
payload.next_hop_afi = p.nh_proto();
} else if (route::path::special_t::LOCAL == p.type()) {
payload.is_local = 1;
}
}
route::path
from_vpp(const vapi_type_fib_path& p, const nh_proto_t& nhp)
{
if (p.is_local) {
return route::path(route::path::special_t::LOCAL);
} else if (p.is_drop) {
return route::path(route::path::special_t::DROP);
} else if (p.is_unreach) {
return route::path(route::path::special_t::UNREACH);
} else if (p.is_prohibit) {
return route::path(route::path::special_t::PROHIBIT);
} else {
boost::asio::ip::address address =
from_bytes(nh_proto_t::IPV6 == nhp, p.next_hop);
std::shared_ptr<interface> itf = interface::find(p.sw_if_index);
if (itf) {
if (p.is_dvr) {
return route::path(*itf, nhp, route::path::flags_t::DVR, p.weight,
p.preference);
} else {
return route::path(address, *itf, p.weight, p.preference);
}
} else {
std::shared_ptr<route_domain> rd = route_domain::find(p.table_id);
if (rd) {
return route::path(*rd, address, p.weight, p.preference);
}
}
}
VOM_LOG(log_level_t::ERROR) << "cannot decode: ";
return route::path(route::path::special_t::DROP);
}
};
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "mozilla")
* End:
*/
|