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