Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad10741a authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk
Browse files

Implement creating VLAN interfaces

Also, minor improvements for TCU:
- added existsAndIsUp convenience function
- added useCanSockets configuration flag

Bug: 156783614
Test: manual
Change-Id: Ia3d48655067792b712519e25ed48ae0cb657347b
parent bb6e0aed
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ cc_library_static {
        "can.cpp",
        "common.cpp",
        "libnetdevice.cpp",
        "vlan.cpp",
    ],
    export_include_dirs: ["include"],
}
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

#include <libnetdevice/libnetdevice.h>
#include <libnetdevice/can.h>

#include "NetlinkRequest.h"
#include "NetlinkSocket.h"
+21 −0
Original line number Diff line number Diff line
@@ -21,6 +21,17 @@

namespace android::netdevice {

/**
 * Configures libnetdevice to use PF_CAN sockets instead of AF_INET,
 * what requires less permissive SEPolicy rules for a given process.
 *
 * In such case, the process would only be able to control CAN interfaces.
 *
 * TODO(b/158011272): consider less hacky solution
 * \param yes true to use CAN sockets, false for general sockets
 */
void useCanSockets(bool yes);

/**
 * Checks, if the network interface exists.
 *
@@ -37,6 +48,16 @@ bool exists(std::string ifname);
 */
std::optional<bool> isUp(std::string ifname);

/**
 * Checks, if the network interface exists and is up.
 *
 * This is a convenience function to call both exists() and isUp().
 *
 * \param ifname Interface to check
 * \return true if the interface is up, false otherwise
 */
bool existsAndIsUp(const std::string& ifname);

/**
 * Brings network interface up.
 *
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <string>

namespace android::netdevice::vlan {

bool add(const std::string& eth, const std::string& vlan, uint16_t id);

}  // namespace android::netdevice::vlan
+25 −3
Original line number Diff line number Diff line
@@ -27,14 +27,32 @@

namespace android::netdevice {

namespace socketparams {

struct Params {
    int domain;
    int type;
    int protocol;
};

static constexpr Params general = {AF_INET, SOCK_DGRAM, 0};
static constexpr Params can = {PF_CAN, SOCK_RAW, CAN_RAW};

static Params current = general;

}  // namespace socketparams

void useCanSockets(bool yes) {
    socketparams::current = yes ? socketparams::can : socketparams::general;
}

bool exists(std::string ifname) {
    return nametoindex(ifname) != 0;
}

static bool sendIfreq(unsigned long request, struct ifreq& ifr) {
    /* For general interfaces it would be socket(AF_INET, SOCK_DGRAM, 0),
     * but SEPolicy forces us to limit our flexibility here. */
    base::unique_fd sock(socket(PF_CAN, SOCK_RAW, CAN_RAW));
    base::unique_fd sock(socket(socketparams::current.domain, socketparams::current.type,
                                socketparams::current.protocol));
    if (!sock.ok()) {
        LOG(ERROR) << "Can't create socket";
        return false;
@@ -60,6 +78,10 @@ std::optional<bool> isUp(std::string ifname) {
    return ifr.ifr_flags & IFF_UP;
}

bool existsAndIsUp(const std::string& ifname) {
    return exists(ifname) && isUp(ifname).value_or(false);
}

bool up(std::string ifname) {
    struct ifreq ifr = ifreqFromName(ifname);
    if (!sendIfreq(SIOCGIFFLAGS, ifr)) return false;
Loading