Пример #1
0
Файл: rconn.c Проект: ecks/harry
/* Attempts to receive a packet from 'rc'.  If successful, returns the packet;
 * otherwise, returns a null pointer.  The caller is responsible for freeing
 * the packet (with ofpbuf_delete()). */
struct rfpbuf *
rconn_recv(struct rconn *rc)
{
  if (rc->state & (S_ACTIVE | S_IDLE)) {
      struct rfpbuf *buffer;
      int error = vconn_recv(rc->vconn, &buffer);
      if (!error) {
          if (rc->state == S_IDLE) {
              state_transition(rc, S_ACTIVE);
          }
          return buffer;
     } 
     else if (error != EAGAIN) 
     {
       if(error == ECONNRESET)
       {
         printf("The connection has been closed\n");
         rconn_disconnect(rc);
         return NULL;
       }
       else
       {
         printf("An error has occured\n");
         rconn_disconnect(rc);
       }
     }
  }
  return NULL;
}
Пример #2
0
static void
failover_periodic_cb(void *context_)
{
	struct failover_context *context = context_;
	char *curr_peer = NULL;
	char *prev_peer = NULL;

	if (rconn_is_connected(context->remote_rconn))
		return;

	if (!is_timed_out(context->peers[context->index],
			  context->settings->max_backoff)) {
		return;
	}

	rconn_disconnect(context->remote_rconn);
	prev_peer = (char *)context->settings->controller_names[context->index];
	context->index = (context->index + 1)
		% context->settings->num_controllers;
	curr_peer = (char *)context->settings->controller_names[context->index];
	rconn_connect(context->remote_rconn,
		      context->settings->controller_names[context->index]);
	context->peers[context->index]->epoch = time_now();
	VLOG_INFO("Switching over to %s, from %s", curr_peer, prev_peer);
}
Пример #3
0
Файл: rconn.c Проект: ecks/harry
/* Drops any existing connection on 'rc', then sets up 'rc' to connect to
 * 'target' and reconnect as needed.  'target' should be a remote OpenFlow
 * target in a form acceptable to vconn_open().
 *
 * If 'name' is nonnull, then it is used in log messages in place of 'target'.
 * It should presumably give more information to a human reader than 'target',
 * but it need not be acceptable to vconn_open(). */
void
rconn_connect(struct rconn *rc, const char *target)
{
    rconn_disconnect(rc);
    rconn_set_target__(rc, target);
    reconnect(rc);
}
Пример #4
0
/* Drops any existing connection on 'rc', then sets up 'rc' to connect to
 * 'target' and reconnect as needed.  'target' should be a remote OpenFlow
 * target in a form acceptable to vconn_open().
 *
 * If 'name' is nonnull, then it is used in log messages in place of 'target'.
 * It should presumably give more information to a human reader than 'target',
 * but it need not be acceptable to vconn_open(). */
void
rconn_connect(struct rconn *rc, const char *target, const char *name)
{
    rconn_disconnect(rc);
    rconn_set_target__(rc, target, name);
    rc->reliable = true;
    reconnect(rc);
}
Пример #5
0
int
rconn_connect(struct rconn *rc, const char *name)
{
    rconn_disconnect(rc);
    free(rc->name);
    rc->name = xstrdup(name);
    rc->reliable = true;
    return reconnect(rc);
}
Пример #6
0
Файл: rconn.c Проект: ecks/harry
/* Drops any existing connection on 'rc', then configures 'rc' to use 
 * 'vconn'.  If the connection on 'vconn' drops, 'rc' will not reconnect on it
 * own. 
 * 
 * By default, the target obtained from vconn_get_name(vconn) is used in log
 * messages.  If 'name' is nonnull, then it is used instead.  It should 
 * presumably give more information to a human reader than the target, but it 
 * need not be acceptable to vconn_open(). */
void rconn_connect_unreliably(struct rconn *rc, struct vconn *vconn, const char *name)
{    
  assert(vconn != NULL);    
  rconn_disconnect(rc);
  rconn_set_target__(rc, vconn_get_name(vconn));    
//  rc->reliable = false;    
  rc->vconn = vconn;    
//  rc->last_connected = time_now();
  state_transition(rc, S_ACTIVE);
}
Пример #7
0
void
rconn_connect_unreliably(struct rconn *rc,
                         const char *name, struct vconn *vconn)
{
    assert(vconn != NULL);
    rconn_disconnect(rc);
    free(rc->name);
    rc->name = xstrdup(name);
    rc->reliable = false;
    rc->vconn = vconn;
    rc->last_connected = time_now();
    state_transition(rc, S_ACTIVE);
}
Пример #8
0
Файл: rconn.c Проект: ecks/harry
static void
run_CONNECTING(struct rconn *rc)
{
    int retval = vconn_connect(rc->vconn);
    if (!retval) {
        printf("%s: connected", rc->target);
        state_transition(rc, S_ACTIVE);
    } else if (retval != EAGAIN) {
            printf("%s: connection failed (%s)",
                      rc->target, strerror(retval));
        rconn_disconnect(rc);
    }
}
Пример #9
0
Файл: rconn.c Проект: ecks/harry
/* Tries to send a packet from 'rc''s send buffer.  Returns 0 if successful,
 * otherwise a positive errno value. */
static int
try_send(struct rconn *rc, struct rfpbuf * msg)
{
  int retval;

  retval = vconn_send(rc->vconn, msg);
  if(retval)
  {
    if(retval != EAGAIN)
    {
      rconn_disconnect(rc);
    }
    return retval;
  }

  return 0;
}
Пример #10
0
Файл: rconn.c Проект: ecks/harry
static void
reconnect(struct rconn *rc)
{
    int retval;

    retval = vconn_open(rc->target, RFP10_VERSION, &rc->vconn, DSCP_DEFAULT);
    if (!retval) {
//        rc->remote_ip = vconn_get_remote_ip(rc->vconn);
//        rc->local_ip = vconn_get_local_ip(rc->vconn);
//        rc->remote_port = vconn_get_remote_port(rc->vconn);
        state_transition(rc, S_CONNECTING);
    } 
    else 
    {
        printf("%s: connection failed (%s)", rc->target, strerror(retval));
        rconn_disconnect(rc);
    }
}
Пример #11
0
/* Processes 'msg', which should be an OpenFlow received on 'rconn', according
 * to the learning switch state in 'sw'.  The most likely result of processing
 * is that flow-setup and packet-out OpenFlow messages will be sent out on
 * 'rconn'.  */
static void
lswitch_process_packet(struct lswitch *sw, const struct ofpbuf *msg)
{
    enum ofptype type;
    struct ofpbuf b;

    b = *msg;
    if (ofptype_pull(&type, &b)) {
        return;
    }

    if (sw->state == S_FEATURES_REPLY
        && type != OFPTYPE_ECHO_REQUEST
        && type != OFPTYPE_FEATURES_REPLY) {
        return;
    }

    if (type == OFPTYPE_ECHO_REQUEST) {
        process_echo_request(sw, msg->data);
    } else if (type == OFPTYPE_FEATURES_REPLY) {
        if (sw->state == S_FEATURES_REPLY) {
            if (!process_switch_features(sw, msg->data)) {
                sw->state = S_SWITCHING;
            } else {
                rconn_disconnect(sw->rconn);
            }
        }
    } else if (type == OFPTYPE_PACKET_IN) {
        process_packet_in(sw, msg->data);
    } else if (type == OFPTYPE_FLOW_REMOVED) {
        /* Nothing to do. */
    } else if (VLOG_IS_DBG_ENABLED()) {
        char *s = ofp_to_string(msg->data, msg->size, 2);
        VLOG_DBG_RL(&rl, "%016llx: OpenFlow packet ignored: %s",
                    sw->datapath_id, s);
        free(s);
    }
}