blob: 1e3022483e4308acd29e6f78439f5a3fd6ee7c99 [file] [log] [blame]
Hugo Benichi7d9d8db2020-03-30 15:56:56 +09001// Copyright 2020 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/routing_service.h"
Hugo Benichi7d9d8db2020-03-30 15:56:56 +09006
7#include <iostream>
8
9#include <base/logging.h>
10
Garrick Evans3388a032020-03-24 11:25:55 +090011namespace patchpanel {
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090012
13RoutingService::RoutingService() {}
14
15int RoutingService::GetSockopt(
16 int sockfd, int level, int optname, void* optval, socklen_t* optlen) {
17 return getsockopt(sockfd, level, optname, optval, optlen);
18}
19
20int RoutingService::SetSockopt(
21 int sockfd, int level, int optname, const void* optval, socklen_t optlen) {
22 return setsockopt(sockfd, level, optname, optval, optlen);
23}
24
Hugo Benichi08805972020-07-15 22:34:57 +090025bool RoutingService::SetFwmark(int sockfd, Fwmark mark, Fwmark mask) {
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090026 uint32_t fwmark_value = 0;
27 socklen_t fwmark_len = sizeof(fwmark_value);
28 if (GetSockopt(sockfd, SOL_SOCKET, SO_MARK, &fwmark_value, &fwmark_len) < 0) {
Hugo Benichi08805972020-07-15 22:34:57 +090029 PLOG(ERROR) << "SetFwmark mark=" << mark.ToString()
30 << " mask=" << mask.ToString()
31 << " getsockopt SOL_SOCKET SO_MARK failed";
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090032 return false;
33 }
34
Hugo Benichi08805972020-07-15 22:34:57 +090035 fwmark_value = (mark & mask).Value() | (fwmark_value & ~mask.Value());
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090036
37 fwmark_len = sizeof(fwmark_value);
38 if (SetSockopt(sockfd, SOL_SOCKET, SO_MARK, &fwmark_value, fwmark_len) < 0) {
Hugo Benichi08805972020-07-15 22:34:57 +090039 PLOG(ERROR) << "SetFwmark mark=" << mark.ToString()
40 << " mask=" << mask.ToString()
41 << " setsockopt SOL_SOCKET SO_MARK failed";
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090042 return false;
43 }
44
45 return true;
46}
47
48bool RoutingService::SetVpnFwmark(
49 int sockfd, patchpanel::SetVpnIntentRequest::VpnRoutingPolicy policy) {
Hugo Benichi08805972020-07-15 22:34:57 +090050 Fwmark mark = {};
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090051 switch (policy) {
52 case patchpanel::SetVpnIntentRequest::DEFAULT_ROUTING:
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090053 break;
54 case patchpanel::SetVpnIntentRequest::ROUTE_ON_VPN:
Hugo Benichi08805972020-07-15 22:34:57 +090055 mark = kFwmarkRouteOnVpn;
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090056 break;
57 case patchpanel::SetVpnIntentRequest::BYPASS_VPN:
Hugo Benichi08805972020-07-15 22:34:57 +090058 mark = kFwmarkBypassVpn;
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090059 break;
60 default:
61 LOG(ERROR) << "Incorrect SetVpnIntent policy value " << policy;
62 return false;
63 }
Hugo Benichi08805972020-07-15 22:34:57 +090064 LOG(INFO) << "SetFwmark mark=" << mark.ToString()
65 << " mask=" << kFwmarkVpnMask.ToString()
66 << " getsockopt SOL_SOCKET SO_MARK";
Hugo Benichi7d9d8db2020-03-30 15:56:56 +090067 return SetFwmark(sockfd, mark, kFwmarkVpnMask);
68}
69
Garrick Evans3388a032020-03-24 11:25:55 +090070} // namespace patchpanel