示例#1
0
/* Features Request packet receive. */
lagopus_result_t
ofp_features_request_handle(struct channel *channel, struct pbuf *pbuf,
                            struct ofp_header *xid_header,
                            struct ofp_error *error) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct pbuf *send_pbuf = NULL;

  /* Parse packet. */
  ret = ofp_header_handle(channel, pbuf, error);
  if (ret == LAGOPUS_RESULT_OK) {
    /* Features request reply. */
    ret = ofp_features_reply_create(channel, &send_pbuf,
                                    xid_header);
    if (ret == LAGOPUS_RESULT_OK) {
      features_request_trace(xid_header);

      channel_send_packet(channel, send_pbuf);
      ret = LAGOPUS_RESULT_OK;
    } else {
      lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
    }
  }

  if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) {
    channel_pbuf_list_unget(channel, send_pbuf);
  }

  return ret;
}
/* Experimenter packet receive. */
lagopus_result_t
ofp_experimenter_request_handle(struct channel *channel, struct pbuf *pbuf,
                                struct ofp_header *xid_header) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct pbuf *send_pbuf = NULL;
  struct ofp_experimenter_header exper_req;

  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL) {
    /* Parse packet. */
    ret = ofp_experimenter_header_decode(pbuf, &exper_req);
    if (ret == LAGOPUS_RESULT_OK) {
      /* Experimenter request reply. */
      ret = ofp_experimenter_reply_create(channel, &send_pbuf,
                                          xid_header, &exper_req);
      if (ret == LAGOPUS_RESULT_OK) {
        channel_send_packet(channel, send_pbuf);
        ret = LAGOPUS_RESULT_OK;
      } else {
        lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
      ret = LAGOPUS_RESULT_OFP_ERROR;
    }

    if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) {
      channel_pbuf_list_unget(channel, send_pbuf);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
lagopus_result_t
ofp_get_async_request_handle(struct channel *channel,
                             struct pbuf *pbuf,
                             struct ofp_header *xid_header,
                             struct ofp_error *error) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct pbuf *send_pbuf = NULL;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {

    ret = pbuf_plen_check(pbuf, xid_header->length);

    if (ret == LAGOPUS_RESULT_OK) {
      /* Parse packet. */
      ret = ofp_header_handle(channel, pbuf, error);

      if (ret == LAGOPUS_RESULT_OK) {
        /* dump trace. */
        get_async_request_trace(xid_header);

        /* Reply send.*/
        ret = ofp_get_async_reply_create(channel, &send_pbuf,
                                         xid_header);

        if (ret == LAGOPUS_RESULT_OK) {
          channel_send_packet(channel, send_pbuf);
        } else {
          lagopus_msg_warning("FAILED (%s).\n",
                              lagopus_error_get_string(ret));
        }
      } else {
        lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
        ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
        ret = LAGOPUS_RESULT_OFP_ERROR;
      }

      if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) {
        channel_pbuf_list_unget(channel, send_pbuf);
      }
    } else {
      lagopus_msg_warning("bad length.\n");
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      ret = LAGOPUS_RESULT_OFP_ERROR;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
STATIC lagopus_result_t
ofp_role_reply_create(struct channel *channel,
                      struct pbuf **pbuf,
                      struct ofp_header *xid_header,
                      struct ofp_role_request *role_request) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  /* reply is ofp_role_request structure. */
  struct ofp_role_request role_reply;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && role_request != NULL) {
    /* alloc */
    *pbuf = channel_pbuf_list_get(channel,
                                  sizeof(struct ofp_role_request));
    if (*pbuf != NULL) {
      pbuf_plen_set(*pbuf, sizeof(struct ofp_role_request));

      /* Fill in header. */
      ofp_header_set(&role_reply.header,
                     channel_version_get(channel),
                     OFPT_ROLE_REPLY,
                     (uint16_t) pbuf_plen_get(*pbuf),
                     xid_header->xid);

      role_reply.role = role_request->role;
      memset(role_reply.pad, 0, sizeof(role_request->pad));
      role_reply.generation_id = role_request->generation_id;

      /* Encode message. */
      ret = ofp_role_request_encode(*pbuf, &role_reply);
      if (ret != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("FAILED (%s).\n",
                            lagopus_error_get_string(ret));
      }

      if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) {
        channel_pbuf_list_unget(channel, *pbuf);
        *pbuf = NULL;
      }
    } else {
      lagopus_msg_warning("Can't allocate pbuf.\n");
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
示例#5
0
static lagopus_result_t
ofp_write_channel(struct channel *channel,
                  struct pbuf *pbuf) {
  lagopus_result_t ret = LAGOPUS_RESULT_OK;
  struct pbuf *send_pbuf = NULL;
  uint16_t len = 0;

  if (channel != NULL && pbuf != NULL) {
    ret = pbuf_length_get(pbuf, &len);

    if (ret == LAGOPUS_RESULT_OK) {
      send_pbuf = channel_pbuf_list_get(channel,
                                        (size_t) len);
      if (send_pbuf != NULL) {
        /* Copy pbuf. */
        ret = pbuf_copy(send_pbuf, pbuf);

        if (ret == LAGOPUS_RESULT_OK) {
          ret = ofp_header_packet_set(channel, send_pbuf);

          if (ret == LAGOPUS_RESULT_OK) {
            channel_send_packet(channel, send_pbuf);
            ret = LAGOPUS_RESULT_OK;
          } else {
            lagopus_msg_warning("FAILED (%s).\n",
                                lagopus_error_get_string(ret));
          }
        } else {
          lagopus_msg_warning("FAILED (%s).\n",
                              lagopus_error_get_string(ret));
        }
      } else {
        lagopus_msg_warning("Can't allocate pbuf.\n");
        ret = LAGOPUS_RESULT_NO_MEMORY;
      }
    } else {
      lagopus_msg_warning("FAILED (%s).\n",
                          lagopus_error_get_string(ret));
    }

    if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) {
      channel_pbuf_list_unget(channel, send_pbuf);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
STATIC lagopus_result_t
ofp_get_async_reply_create(struct channel *channel,
                           struct pbuf **pbuf,
                           struct ofp_header *xid_header) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct ofp_async_config async_config;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL) {
    /* alloc */
    *pbuf = channel_pbuf_list_get(channel,
                                  sizeof(struct ofp_async_config));
    if (*pbuf != NULL) {
      pbuf_plen_set(*pbuf, sizeof(struct ofp_async_config));

      /* Copy packet_in_mask, port_status_mask, flow_removed_mask. */
      channel_role_mask_get(channel, &async_config);

      /* Fill in header. */
      ofp_header_set(&async_config.header,
                     channel_version_get(channel),
                     OFPT_GET_ASYNC_REPLY,
                     (uint16_t) pbuf_plen_get(*pbuf),
                     xid_header->xid);

      /* Encode message. */
      ret = ofp_async_config_encode(*pbuf, &async_config);

      if (ret != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("FAILED : ofp_async_config_encode (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("Can't allocate pbuf.\n");
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }

    if (ret != LAGOPUS_RESULT_OK &&  *pbuf != NULL) {
      channel_pbuf_list_unget(channel, *pbuf);
      *pbuf = NULL;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
示例#7
0
/* Send switch features reply. */
STATIC lagopus_result_t
ofp_features_reply_create(struct channel *channel,
                          struct pbuf **pbuf,
                          struct ofp_header *xid_header) {
  struct ofp_switch_features features;
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  if (channel != NULL && pbuf != NULL && xid_header != NULL) {
    /* alloc */
    *pbuf = channel_pbuf_list_get(channel,
                                  sizeof(struct ofp_switch_features));
    if (*pbuf != NULL) {
      pbuf_plen_set(*pbuf, sizeof(struct ofp_switch_features));

      ret = features_reply_features_get(channel, &features);
      if (ret == LAGOPUS_RESULT_OK) {
        /* Fill in header. */
        ofp_header_set(&features.header, channel_version_get(channel),
                       OFPT_FEATURES_REPLY, (uint16_t) pbuf_plen_get(*pbuf),
                       xid_header->xid);

        /* Encode message. */
        ret = ofp_switch_features_encode(*pbuf, &features);
        if (ret != LAGOPUS_RESULT_OK) {
          lagopus_msg_warning("FAILED (%s).\n",
                              lagopus_error_get_string(ret));
        }
      } else {
        lagopus_msg_warning("FAILED (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("Can't allocate pbuf.\n");
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }

    if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) {
      channel_pbuf_list_unget(channel, *pbuf);
      *pbuf = NULL;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
/* Send experimenter reply. */
STATIC lagopus_result_t
ofp_experimenter_reply_create(struct channel *channel,
                              struct pbuf **pbuf,
                              struct ofp_header *xid_header,
                              struct ofp_experimenter_header *exper_req) {
  struct ofp_experimenter_header exper_reply;
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && exper_req != NULL) {
    *pbuf = NULL;
    /* alloc */
    *pbuf = channel_pbuf_list_get(channel,
                                  sizeof(struct ofp_experimenter_header));
    if (*pbuf != NULL) {
      pbuf_plen_set(*pbuf, sizeof(struct ofp_experimenter_header));

      exper_reply.experimenter = exper_req->experimenter;
      exper_reply.exp_type = exper_req->exp_type;

      /* Fill in header. */
      ofp_header_set(&exper_reply.header, channel_version_get(channel),
                     OFPT_EXPERIMENTER, (uint16_t) pbuf_plen_get(*pbuf),
                     xid_header->xid);

      /* Encode message. */
      ret = ofp_experimenter_header_encode(*pbuf, &exper_reply);
      if (ret != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("FAILED (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("Can't allocate pbuf.\n");
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }

    if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) {
      channel_pbuf_list_unget(channel, *pbuf);
      *pbuf = NULL;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
lagopus_result_t
ofp_role_request_handle(struct channel *channel,
                        struct pbuf *pbuf,
                        struct ofp_header *xid_header,
                        struct ofp_error *error) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct ofp_role_request role_request;
  struct ofp_role_request modified_role_request;
  struct pbuf *send_pbuf = NULL;
  uint64_t dpid;

  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    /* Parse packet. */
    ret = ofp_role_request_decode(pbuf, &role_request);

    if (ret == LAGOPUS_RESULT_OK) {
      /* dump trace. */
      role_request_trace(&role_request);

      ret = role_check(role_request.role, error);

      if (ret == LAGOPUS_RESULT_OK) {
        dpid = channel_dpid_get(channel);
        if (ofp_role_generation_id_check(dpid, role_request.role,
                                         role_request.generation_id) == true) {
          /* copy role request. */
          modified_role_request = role_request;
          ret = ofp_role_channel_update(channel,
                                        &modified_role_request,
                                        dpid);
          if (ret == LAGOPUS_RESULT_OK) {
            /* Reply send.*/
            ret = ofp_role_reply_create(channel, &send_pbuf,
                                        xid_header, &modified_role_request);
            if (ret == LAGOPUS_RESULT_OK) {
              channel_send_packet(channel, send_pbuf);
            } else {
              lagopus_msg_warning("FAILED (%s).\n",
                                  lagopus_error_get_string(ret));
            }
          } else {
            lagopus_msg_warning("FAILED (%s).\n",
                                lagopus_error_get_string(ret));
          }
        } else {
          lagopus_msg_warning("bad generation_id.\n");
          ofp_error_set(error, OFPET_ROLE_REQUEST_FAILED, OFPRRFC_STALE);
          ret = LAGOPUS_RESULT_OFP_ERROR;
        }

        if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) {
          channel_pbuf_list_unget(channel, send_pbuf);
        }
      }
    } else {
      lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      ret = LAGOPUS_RESULT_OFP_ERROR;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}