mirror of
https://github.com/openvswitch/ovs
synced 2025-10-19 14:37:21 +00:00
rconn_add_monitor() tries to check the version of the controller connection being monitored, so that it can decide what OpenFlow version to tell the monitor connection to negotiate. But at any given time an rconn may not have a controller connection (e.g. during backoff), so rc->vconn may be null and thus vconn_get_version(rc->vconn) dereferences a null pointer. Fixing the problem in a local way would require the rconn to remember the previous version negotiated, and that fails if the rconn hasn't yet connected or if the next connection negotiates a new version. This commit instead adds the ability to a vconn to accept any OpenFlow message version and modifies "ovs-ofctl snoop" to use that feature, thus removing the need to negotiate the "correct" version on snoops. Bug #14265. Reported-by: Pratap Reddy <preddy@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Ethan Jackson <ethan@nicira.com>
95 lines
3.2 KiB
C
95 lines
3.2 KiB
C
/*
|
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef VCONN_H
|
|
#define VCONN_H 1
|
|
|
|
#include <stdbool.h>
|
|
#include "openvswitch/types.h"
|
|
#include "openflow/openflow.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct list;
|
|
struct ofpbuf;
|
|
struct pvconn;
|
|
struct vconn;
|
|
|
|
void vconn_usage(bool active, bool passive, bool bootstrap);
|
|
|
|
/* Active vconns: virtual connections to OpenFlow devices. */
|
|
int vconn_verify_name(const char *name);
|
|
int vconn_open(const char *name, uint32_t allowed_versions, uint8_t dscp,
|
|
struct vconn **vconnp);
|
|
void vconn_close(struct vconn *);
|
|
const char *vconn_get_name(const struct vconn *);
|
|
|
|
uint32_t vconn_get_allowed_versions(const struct vconn *vconn);
|
|
void vconn_set_allowed_versions(struct vconn *vconn,
|
|
uint32_t allowed_versions);
|
|
int vconn_get_version(const struct vconn *);
|
|
void vconn_set_recv_any_version(struct vconn *);
|
|
|
|
ovs_be32 vconn_get_remote_ip(const struct vconn *);
|
|
ovs_be16 vconn_get_remote_port(const struct vconn *);
|
|
ovs_be32 vconn_get_local_ip(const struct vconn *);
|
|
ovs_be16 vconn_get_local_port(const struct vconn *);
|
|
|
|
int vconn_connect(struct vconn *);
|
|
int vconn_recv(struct vconn *, struct ofpbuf **);
|
|
int vconn_send(struct vconn *, struct ofpbuf *);
|
|
int vconn_recv_xid(struct vconn *, ovs_be32 xid, struct ofpbuf **);
|
|
int vconn_transact(struct vconn *, struct ofpbuf *, struct ofpbuf **);
|
|
int vconn_transact_noreply(struct vconn *, struct ofpbuf *, struct ofpbuf **);
|
|
int vconn_transact_multiple_noreply(struct vconn *, struct list *requests,
|
|
struct ofpbuf **replyp);
|
|
|
|
void vconn_run(struct vconn *);
|
|
void vconn_run_wait(struct vconn *);
|
|
|
|
int vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp,
|
|
struct vconn **);
|
|
int vconn_connect_block(struct vconn *);
|
|
int vconn_send_block(struct vconn *, struct ofpbuf *);
|
|
int vconn_recv_block(struct vconn *, struct ofpbuf **);
|
|
|
|
enum vconn_wait_type {
|
|
WAIT_CONNECT,
|
|
WAIT_RECV,
|
|
WAIT_SEND
|
|
};
|
|
void vconn_wait(struct vconn *, enum vconn_wait_type);
|
|
void vconn_connect_wait(struct vconn *);
|
|
void vconn_recv_wait(struct vconn *);
|
|
void vconn_send_wait(struct vconn *);
|
|
|
|
/* Passive vconns: virtual listeners for incoming OpenFlow connections. */
|
|
int pvconn_verify_name(const char *name);
|
|
int pvconn_open(const char *name, uint32_t allowed_versions, uint8_t dscp,
|
|
struct pvconn **pvconnp);
|
|
const char *pvconn_get_name(const struct pvconn *);
|
|
void pvconn_close(struct pvconn *);
|
|
int pvconn_accept(struct pvconn *, struct vconn **);
|
|
void pvconn_wait(struct pvconn *);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* vconn.h */
|