tunnel: Accept 'set options:tos' as hex value.
[sliver-openvswitch.git] / lib / netdev-vport.c
index 0577bd3..a9eb3eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011 Nicira Networks.
+ * Copyright (c) 2010, 2011, 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -131,7 +131,8 @@ netdev_vport_get_vport_type(const struct netdev *netdev)
 
     return (is_vport_class(class) ? vport_class_cast(class)->type
             : class == &netdev_internal_class ? OVS_VPORT_TYPE_INTERNAL
-            : class == &netdev_linux_class ? OVS_VPORT_TYPE_NETDEV
+            : (class == &netdev_linux_class ||
+               class == &netdev_tap_class) ? OVS_VPORT_TYPE_NETDEV
             : OVS_VPORT_TYPE_UNSPEC);
 }
 
@@ -197,6 +198,7 @@ netdev_vport_destroy(struct netdev_dev *netdev_dev_)
 {
     struct netdev_dev_vport *netdev_dev = netdev_dev_vport_cast(netdev_dev_);
 
+    ofpbuf_delete(netdev_dev->options);
     route_table_unregister();
     free(netdev_dev);
 }
@@ -457,7 +459,7 @@ netdev_vport_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
 }
 
 static int
-netdev_vport_get_status(const struct netdev *netdev, struct shash *sh)
+netdev_vport_get_drv_info(const struct netdev *netdev, struct shash *sh)
 {
     const char *iface = netdev_vport_get_tnl_iface(netdev);
 
@@ -578,6 +580,7 @@ parse_tunnel_config(const char *name, const char *type,
     struct shash_node *node;
     bool ipsec_mech_set = false;
     ovs_be32 daddr = htonl(0);
+    ovs_be32 saddr = htonl(0);
     uint32_t flags;
 
     flags = TNL_F_DF_DEFAULT | TNL_F_PMTUD | TNL_F_HDR_CACHE;
@@ -603,14 +606,18 @@ parse_tunnel_config(const char *name, const char *type,
             if (lookup_ip(node->data, &in_addr)) {
                 VLOG_WARN("%s: bad %s 'local_ip'", name, type);
             } else {
-                nl_msg_put_be32(options, OVS_TUNNEL_ATTR_SRC_IPV4,
-                                in_addr.s_addr);
+                saddr = in_addr.s_addr;
             }
         } else if (!strcmp(node->name, "tos")) {
             if (!strcmp(node->data, "inherit")) {
                 flags |= TNL_F_TOS_INHERIT;
             } else {
-                nl_msg_put_u8(options, OVS_TUNNEL_ATTR_TOS, atoi(node->data));
+                char *endptr;
+                int tos;
+                tos = strtol(node->data, &endptr, 0);
+                if (*endptr == '\0') {
+                    nl_msg_put_u8(options, OVS_TUNNEL_ATTR_TOS, tos);
+                }
             }
         } else if (!strcmp(node->name, "ttl")) {
             if (!strcmp(node->data, "inherit")) {
@@ -707,6 +714,14 @@ parse_tunnel_config(const char *name, const char *type,
     }
     nl_msg_put_be32(options, OVS_TUNNEL_ATTR_DST_IPV4, daddr);
 
+    if (saddr) {
+        if (ip_is_multicast(daddr)) {
+            VLOG_WARN("%s: remote_ip is multicast, ignoring local_ip", name);
+        } else {
+            nl_msg_put_be32(options, OVS_TUNNEL_ATTR_SRC_IPV4, saddr);
+        }
+    }
+
     nl_msg_put_u32(options, OVS_TUNNEL_ATTR_FLAGS, flags);
 
     return 0;
@@ -804,7 +819,7 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
         smap_add(args, "tos", "inherit");
     } else if (a[OVS_TUNNEL_ATTR_TOS]) {
         int tos = nl_attr_get_u8(a[OVS_TUNNEL_ATTR_TOS]);
-        shash_add(args, "tos", xasprintf("%d", tos));
+        shash_add(args, "tos", xasprintf("0x%x", tos));
     }
 
     if (flags & TNL_F_CSUM) {
@@ -913,7 +928,6 @@ unparse_patch_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
                                                             \
     NULL,                       /* get_features */          \
     NULL,                       /* set_advertisements */    \
-    NULL,                       /* get_vlan_vid */          \
                                                             \
     NULL,                       /* set_policing */          \
     NULL,                       /* get_qos_types */         \
@@ -944,15 +958,15 @@ netdev_vport_register(void)
 {
     static const struct vport_class vport_classes[] = {
         { OVS_VPORT_TYPE_GRE,
-          { "gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
+          { "gre", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
           parse_tunnel_config, unparse_tunnel_config },
 
         { OVS_VPORT_TYPE_GRE,
-          { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_status) },
+          { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
           parse_tunnel_config, unparse_tunnel_config },
 
         { OVS_VPORT_TYPE_CAPWAP,
-          { "capwap", VPORT_FUNCTIONS(netdev_vport_get_status) },
+          { "capwap", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
           parse_tunnel_config, unparse_tunnel_config },
 
         { OVS_VPORT_TYPE_PATCH,