Implement creating VLAN interfaces

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

Bug: 156783614
Test: manual
Change-Id: Ia3d48655067792b712519e25ed48ae0cb657347b
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index b051442..827f8f3 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -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 @@
     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;