2 * Copyright (c) 2017 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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "vom/dhcp_client_cmds.hpp"
17 #include "vom/route_api_types.hpp"
19 DEFINE_VAPI_MSG_IDS_DHCP_API_JSON;
22 namespace dhcp_client_cmds {
24 bind_cmd::bind_cmd(HW::item<bool>& item,
26 const std::string& hostname,
27 const l2_address_t& client_id,
28 bool set_broadcast_flag,
29 const ip_dscp_t& dscp)
32 , m_hostname(hostname)
33 , m_client_id(client_id)
34 , m_set_broadcast_flag(set_broadcast_flag)
40 bind_cmd::operator==(const bind_cmd& other) const
42 return ((m_itf == other.m_itf) && (m_hostname == other.m_hostname));
46 bind_cmd::issue(connection& con)
48 msg_t req(con.ctx(), std::ref(*this));
50 auto& payload = req.get_request().get_payload();
52 payload.client.sw_if_index = m_itf.value();
53 payload.client.pid = getpid();
54 payload.client.want_dhcp_event = 1;
55 payload.client.set_broadcast_flag = m_set_broadcast_flag;
56 payload.client.dscp = to_api(m_dscp);
58 memset(payload.client.hostname, 0, sizeof(payload.client.hostname));
59 memcpy(payload.client.hostname, m_hostname.c_str(),
60 std::min(sizeof(payload.client.hostname), m_hostname.length()));
62 memset(payload.client.id, 0, sizeof(payload.client.id));
63 payload.client.id[0] = 1;
64 std::copy_n(begin(m_client_id.bytes),
65 std::min(sizeof(payload.client.id), m_client_id.bytes.size()),
66 payload.client.id + 1);
68 VAPI_CALL(req.execute());
74 bind_cmd::to_string() const
77 s << "Dhcp-client-bind: " << m_hw_item.to_string()
78 << " itf:" << m_itf.to_string() << " hostname:" << m_hostname
79 << " client_id:[" << m_client_id << "] "
80 << "dscp:" << m_dscp.to_string();
85 unbind_cmd::unbind_cmd(HW::item<bool>& item,
87 const std::string& hostname)
90 , m_hostname(hostname)
95 unbind_cmd::operator==(const unbind_cmd& other) const
97 return ((m_itf == other.m_itf) && (m_hostname == other.m_hostname));
101 unbind_cmd::issue(connection& con)
103 msg_t req(con.ctx(), std::ref(*this));
105 auto& payload = req.get_request().get_payload();
107 payload.client.sw_if_index = m_itf.value();
108 payload.client.pid = getpid();
109 payload.client.want_dhcp_event = 0;
111 memcpy(payload.client.hostname, m_hostname.c_str(),
112 std::min(sizeof(payload.client.hostname), m_hostname.length()));
114 VAPI_CALL(req.execute());
117 m_hw_item.set(rc_t::NOOP);
123 unbind_cmd::to_string() const
125 std::ostringstream s;
126 s << "Dhcp-client-unbind: " << m_hw_item.to_string()
127 << " itf:" << m_itf.to_string() << " hostname:" << m_hostname;
132 events_cmd::events_cmd(dhcp_client::event_listener& el)
133 : event_cmd(el.status())
138 events_cmd::~events_cmd()
140 VOM_LOG(log_level_t::INFO) << "DHCP events destroyed";
144 events_cmd::operator==(const events_cmd& other) const
150 events_cmd::issue(connection& con)
153 * Set the call back to handle DHCP complete envets.
155 m_reg.reset(new reg_t(con.ctx(), std::ref(*this)));
158 * return in-progress so the command stays in the pending list.
164 events_cmd::retire(connection& con)
171 for (auto& msg : *this) {
172 auto& payload = msg.get_payload();
174 const dhcp_client::state_t& s =
175 dhcp_client::state_t::from_vpp(payload.lease.state);
176 route::prefix_t pfx(payload.lease.is_ipv6,
177 (uint8_t*)&payload.lease.host_address.un,
178 payload.lease.mask_width);
179 std::shared_ptr<interface> itf = interface::find(payload.lease.sw_if_index);
182 std::shared_ptr<dhcp_client::lease_t> ev =
183 std::make_shared<dhcp_client::lease_t>(
184 s, itf, from_bytes(0, (uint8_t*)&payload.lease.router_address.un),
185 pfx, reinterpret_cast<const char*>(payload.lease.hostname),
186 mac_address_t(payload.lease.host_mac));
187 m_listener.handle_dhcp_event(ev);
189 VOM_LOG(log_level_t::INFO) << "DHCP: " << ev->to_string();
191 VOM_LOG(log_level_t::ERROR) << "DHCP: no interface: "
192 << payload.lease.sw_if_index;
200 events_cmd::to_string() const
202 return ("dhcp-events");
210 dump_cmd::operator==(const dump_cmd& other) const
216 dump_cmd::issue(connection& con)
218 m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
220 VAPI_CALL(m_dump->execute());
228 dump_cmd::to_string() const
230 return ("dhcp-client-dump");
233 }; // namespace dhcp_client_cmds
237 * fd.io coding-style-patch-verification: ON
240 * eval: (c-set-style "mozilla")