vswitchd: In-band rules for Controller are missing after executing force-reload-kmod...
authorAnsis Atteka <aatteka@nicira.com>
Mon, 19 Dec 2011 20:43:34 +0000 (12:43 -0800)
committerAnsis Atteka <aatteka@nicira.com>
Tue, 20 Dec 2011 01:54:13 +0000 (17:54 -0800)
In current implementation vswitchd adds Controller in-band rules only if
there is a route in kernel routing table that might route traffic to the
Controller. But, when executing force-reload-kmod command, network
configuration (e.g. assigned IP addresses, routes) are flushed away,
hence Controller in-band rules are not added.

This commit fixes this limitation and allows vswitchd to add Controller
in-band rules even if there are no routes in the kernel routing table.

Issue: #8625

Signed-off-by: Ansis Atteka <aatteka@nicira.com>
lib/stream.c
lib/stream.h
ofproto/connmgr.c
vswitchd/bridge.c

index 9ba4c518425232054a541c432ee96092a333ba78..4c3583c4fa8663b85a894e79dc06d35588dbebc5 100644 (file)
@@ -724,7 +724,27 @@ pstream_open_with_default_ports(const char *name_,
 
     return error;
 }
-\f
+
+/*
+ * This function extracts IP address and port from the target string.
+ *
+ *     - On success, function returns true and fills *sin structure with port
+ *       and IP address. If port was absent in target string then it will use
+ *       corresponding default port value.
+ *     - On error, function returns false and *sin contains garbage.
+ */
+bool
+stream_parse_target_with_default_ports(const char *target,
+                                       uint16_t default_tcp_port,
+                                       uint16_t default_ssl_port,
+                                       struct sockaddr_in *sin)
+{
+    return (!strncmp(target, "tcp:", 4)
+             && inet_parse_active(target + 4, default_tcp_port, sin)) ||
+            (!strncmp(target, "ssl:", 4)
+             && inet_parse_active(target + 4, default_ssl_port, sin));
+}
+
 /* Attempts to guess the content type of a stream whose first few bytes were
  * the 'size' bytes of 'data'. */
 static enum stream_content_type
index 51a765665af0377d94805f956355d3690b3f6a56..5c111f999e3de4423481d036d9d5302abb68467e 100644 (file)
@@ -23,6 +23,7 @@
 #include <sys/types.h>
 #include "openvswitch/types.h"
 #include "vlog.h"
+#include "socket-util.h"
 
 struct pstream;
 struct stream;
@@ -75,7 +76,11 @@ int pstream_open_with_default_ports(const char *name,
                                     uint16_t default_ptcp_port,
                                     uint16_t default_pssl_port,
                                     struct pstream **);
-\f
+bool stream_parse_target_with_default_ports(const char *target,
+                                           uint16_t default_tcp_port,
+                                           uint16_t default_ssl_port,
+                                           struct sockaddr_in *sin);
+
 /* Error reporting. */
 
 enum stream_content_type {
index 6432ba660ab66a4178f1a80aa1ba1011a3b0891d..1c55b67751457cf1ea0d4a5bf0a479eef7a82ca7 100644 (file)
@@ -587,14 +587,16 @@ update_in_band_remotes(struct connmgr *mgr)
     /* Add all the remotes. */
     HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
         struct sockaddr_in *sin = &addrs[n_addrs];
+        const char *target = rconn_get_target(ofconn->rconn);
 
         if (ofconn->band == OFPROTO_OUT_OF_BAND) {
             continue;
         }
 
-        sin->sin_addr.s_addr = rconn_get_remote_ip(ofconn->rconn);
-        if (sin->sin_addr.s_addr) {
-            sin->sin_port = rconn_get_remote_port(ofconn->rconn);
+        if (stream_parse_target_with_default_ports(target,
+                                                   OFP_TCP_PORT,
+                                                   OFP_SSL_PORT,
+                                                   sin)) {
             n_addrs++;
         }
     }
index 396c7206f319877c644604386168c9f88b86681c..3ae3b0f8b503e10babbc4a36399e69ea211bbebe 100644 (file)
@@ -373,10 +373,10 @@ collect_in_band_managers(const struct ovsrec_open_vswitch *ovs_cfg,
         SSET_FOR_EACH (target, &targets) {
             struct sockaddr_in *sin = &managers[n_managers];
 
-            if ((!strncmp(target, "tcp:", 4)
-                 && inet_parse_active(target + 4, JSONRPC_TCP_PORT, sin)) ||
-                (!strncmp(target, "ssl:", 4)
-                 && inet_parse_active(target + 4, JSONRPC_SSL_PORT, sin))) {
+            if (stream_parse_target_with_default_ports(target,
+                                                       JSONRPC_TCP_PORT,
+                                                       JSONRPC_SSL_PORT,
+                                                       sin)) {
                 n_managers++;
             }
         }