Implement arbitrary bitwise masks for tun_id field.
[sliver-openvswitch.git] / lib / dpif-linux.c
index 870e03e..1d7249c 100644 (file)
 #include "netdev.h"
 #include "netdev-vport.h"
 #include "ofpbuf.h"
+#include "openvswitch/tunnel.h"
 #include "poll-loop.h"
 #include "rtnetlink.h"
+#include "rtnetlink-link.h"
 #include "shash.h"
 #include "svec.h"
 #include "util.h"
@@ -71,7 +73,7 @@ static int get_openvswitch_major(void);
 static int create_minor(const char *name, int minor, struct dpif **dpifp);
 static int open_minor(int minor, struct dpif **dpifp);
 static int make_openvswitch_device(int minor, char **fnp);
-static void dpif_linux_port_changed(const struct rtnetlink_change *,
+static void dpif_linux_port_changed(const struct rtnetlink_link_change *,
                                     void *dpif);
 
 static struct dpif_linux *
@@ -176,7 +178,7 @@ static void
 dpif_linux_close(struct dpif *dpif_)
 {
     struct dpif_linux *dpif = dpif_linux_cast(dpif_);
-    rtnetlink_notifier_unregister(&dpif->port_notifier);
+    rtnetlink_link_notifier_unregister(&dpif->port_notifier);
     shash_destroy(&dpif->changed_ports);
     free(dpif->local_ifname);
     close(dpif->fd);
@@ -227,18 +229,31 @@ dpif_linux_set_drop_frags(struct dpif *dpif_, bool drop_frags)
 }
 
 static void
-translate_vport_type_to_netdev_type(char *type, size_t size)
+translate_vport_type_to_netdev_type(struct odp_port *port)
 {
+    char *type = port->type;
+
     if (!strcmp(type, "netdev")) {
-        ovs_strlcpy(type, "system", size);
+        ovs_strlcpy(type, "system", sizeof port->type);
+    } else if (!strcmp(type, "gre")) {
+        const struct tnl_port_config *config;
+
+        config = (struct tnl_port_config *)port->config;
+        if (config->flags & TNL_F_IPSEC) {
+            ovs_strlcpy(type, "ipsec_gre", sizeof port->type);
+        }
     }
 }
 
 static void
-translate_netdev_type_to_vport_type(char *type, size_t size)
+translate_netdev_type_to_vport_type(struct odp_port *port)
 {
+    char *type = port->type;
+
     if (!strcmp(type, "system")) {
-        ovs_strlcpy(type, "netdev", size);
+        ovs_strlcpy(type, "netdev", sizeof port->type);
+    } else if (!strcmp(type, "ipsec_gre")) {
+        ovs_strlcpy(type, "gre", sizeof port->type);
     }
 }
 
@@ -254,8 +269,8 @@ dpif_linux_port_add(struct dpif *dpif, struct netdev *netdev,
     memset(&port, 0, sizeof port);
     strncpy(port.devname, name, sizeof port.devname);
     strncpy(port.type, type, sizeof port.type);
-    translate_netdev_type_to_vport_type(port.type, sizeof port.type);
     netdev_vport_get_config(netdev, port.config);
+    translate_netdev_type_to_vport_type(&port);
 
     error = do_ioctl(dpif, ODP_VPORT_ATTACH, &port);
     if (!error) {
@@ -277,7 +292,7 @@ dpif_linux_port_query__(const struct dpif *dpif, struct odp_port *port)
 {
     int error = do_ioctl(dpif, ODP_VPORT_QUERY, port);
     if (!error) {
-        translate_vport_type_to_netdev_type(port->type, sizeof port->type);
+        translate_vport_type_to_netdev_type(port);
     }
     return error;
 }
@@ -323,7 +338,7 @@ dpif_linux_port_list(const struct dpif *dpif_, struct odp_port *ports, int n)
     for (i = 0; i < pv.n_ports; i++) {
         struct odp_port *port = &pv.ports[i];
 
-        translate_vport_type_to_netdev_type(port->type, sizeof port->type);
+        translate_vport_type_to_netdev_type(port);
     }
     return pv.n_ports;
 }
@@ -353,7 +368,7 @@ dpif_linux_port_poll_wait(const struct dpif *dpif_)
     if (!shash_is_empty(&dpif->changed_ports) || dpif->change_error) {
         poll_immediate_wake();
     } else {
-        rtnetlink_notifier_wait();
+        rtnetlink_link_notifier_wait();
     }
 }
 
@@ -756,8 +771,9 @@ open_minor(int minor, struct dpif **dpifp)
     fd = open(fn, O_RDONLY | O_NONBLOCK);
     if (fd >= 0) {
         struct dpif_linux *dpif = xmalloc(sizeof *dpif);
-        error = rtnetlink_notifier_register(&dpif->port_notifier,
-                                           dpif_linux_port_changed, dpif);
+        error = rtnetlink_link_notifier_register(&dpif->port_notifier,
+                                                 dpif_linux_port_changed,
+                                                 dpif);
         if (!error) {
             char *name;
 
@@ -785,7 +801,8 @@ open_minor(int minor, struct dpif **dpifp)
 }
 
 static void
-dpif_linux_port_changed(const struct rtnetlink_change *change, void *dpif_)
+dpif_linux_port_changed(const struct rtnetlink_link_change *change,
+                        void *dpif_)
 {
     struct dpif_linux *dpif = dpif_;