1 #include "rtnetlink.hpp"
2 
3 #include "netlink.hpp"
4 
5 #include <linux/rtnetlink.h>
6 
7 namespace phosphor::network::netlink
8 {
9 
10 template <typename Addr>
11 static std::optional<std::tuple<unsigned, InAddrAny>>
12     parse(std::string_view msg)
13 {
14     std::optional<unsigned> ifIdx;
15     std::optional<InAddrAny> gw;
16     while (!msg.empty())
17     {
18         auto [hdr, data] = extractRtAttr(msg);
19         switch (hdr.rta_type)
20         {
21             case RTA_OIF:
22                 ifIdx.emplace(stdplus::raw::copyFrom<int>(data));
23                 break;
24             case RTA_GATEWAY:
25                 gw.emplace(stdplus::raw::copyFrom<Addr>(data));
26                 break;
27         }
28     }
29     if (ifIdx && gw)
30     {
31         return std::make_tuple(*ifIdx, *gw);
32     }
33     return std::nullopt;
34 }
35 
36 std::optional<std::tuple<unsigned, InAddrAny>>
37     gatewayFromRtm(std::string_view msg)
38 {
39     const auto& rtm = extractRtData<rtmsg>(msg);
40     if (rtm.rtm_table != RT_TABLE_MAIN || rtm.rtm_dst_len != 0)
41     {
42         return std::nullopt;
43     }
44     switch (rtm.rtm_family)
45     {
46         case AF_INET:
47             return parse<in_addr>(msg);
48         case AF_INET6:
49             return parse<in6_addr>(msg);
50     }
51     return std::nullopt;
52 }
53 
54 } // namespace phosphor::network::netlink
55