From: Ben Pfaff Date: Tue, 20 Apr 2010 23:36:01 +0000 (-0700) Subject: ofproto: Allow client to pass down extra (IP,port) tuples for in-band. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=917e50e1b8c68cb2a0e8ac36f638f2ba3ecb2de9;p=openvswitch ofproto: Allow client to pass down extra (IP,port) tuples for in-band. ovs-vswitchd needs to be able to tell ofproto where the OVSDB managers are, so that in-band control can allow traffic to it even if there is no connection to the controller yet. This adds the basis for that feature. --- diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 5f2f6f4c..3f9cc90e 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -255,6 +255,9 @@ struct ofproto { /* In-band control. */ struct in_band *in_band; long long int next_in_band_update; + struct sockaddr_in *extra_in_band_remotes; + size_t n_extra_remotes; + /* Flow table. */ struct classifier cls; bool need_revalidate; @@ -525,11 +528,13 @@ update_in_band_remotes(struct ofproto *ofproto) { const struct ofconn *ofconn; struct sockaddr_in *addrs; + size_t max_addrs, n_addrs; bool discovery; - size_t n_addrs; - + size_t i; - addrs = xmalloc(hmap_count(&ofproto->controllers) * sizeof *addrs); + /* Allocate enough memory for as many remotes as we could possibly have. */ + max_addrs = ofproto->n_extra_remotes + hmap_count(&ofproto->controllers); + addrs = xmalloc(max_addrs * sizeof *addrs); n_addrs = 0; /* Add all the remotes. */ @@ -546,6 +551,9 @@ update_in_band_remotes(struct ofproto *ofproto) discovery = true; } } + for (i = 0; i < ofproto->n_extra_remotes; i++) { + addrs[n_addrs++] = ofproto->extra_in_band_remotes[i]; + } /* Create or update or destroy in-band. * @@ -642,6 +650,47 @@ ofproto_set_controllers(struct ofproto *p, } } +static bool +any_extras_changed(const struct ofproto *ofproto, + const struct sockaddr_in *extras, size_t n) +{ + size_t i; + + if (n != ofproto->n_extra_remotes) { + return true; + } + + for (i = 0; i < n; i++) { + const struct sockaddr_in *old = &ofproto->extra_in_band_remotes[i]; + const struct sockaddr_in *new = &extras[i]; + + if (old->sin_addr.s_addr != new->sin_addr.s_addr || + old->sin_port != new->sin_port) { + return true; + } + } + + return false; +} + +/* Sets the 'n' TCP port addresses in 'extras' as ones to which 'ofproto''s + * in-band control should guarantee access, in the same way that in-band + * control guarantees access to OpenFlow controllers. */ +void +ofproto_set_extra_in_band_remotes(struct ofproto *ofproto, + const struct sockaddr_in *extras, size_t n) +{ + if (!any_extras_changed(ofproto, extras, n)) { + return; + } + + free(ofproto->extra_in_band_remotes); + ofproto->n_extra_remotes = n; + ofproto->extra_in_band_remotes = xmemdup(extras, n * sizeof *extras); + + update_in_band_remotes(ofproto); +} + void ofproto_set_desc(struct ofproto *p, const char *mfr_desc, const char *hw_desc, @@ -845,6 +894,7 @@ ofproto_destroy(struct ofproto *p) in_band_destroy(p->in_band); p->in_band = NULL; + free(p->extra_in_band_remotes); ofproto_flush_flows(p); classifier_destroy(&p->cls); diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 32d7623d..c3d71e8d 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -104,6 +104,8 @@ bool ofproto_is_alive(const struct ofproto *); void ofproto_set_datapath_id(struct ofproto *, uint64_t datapath_id); void ofproto_set_controllers(struct ofproto *, const struct ofproto_controller *, size_t n); +void ofproto_set_extra_in_band_remotes(struct ofproto *, + const struct sockaddr_in *, size_t n); void ofproto_set_desc(struct ofproto *, const char *mfr_desc, const char *hw_desc, const char *sw_desc, const char *serial_desc,