Esempio n. 1
0
lagopus_result_t
ofp_port_status_handle(struct port_status *port_status, uint64_t dpid) {
  lagopus_result_t ret;
  struct pbuf *send_pbuf = NULL;

  if (port_status != NULL) {
    /* PortStatus. */
    ret = ofp_port_status_create(port_status, &send_pbuf);
    if (ret == LAGOPUS_RESULT_OK) {
      ret = ofp_role_channel_write(send_pbuf, dpid,
                                   OFPT_PORT_STATUS,
                                   port_status->ofp_port_status.reason);
      if (ret != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("Socket write error (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("FAILED : ofp_port_status_create (%s).\n",
                          lagopus_error_get_string(ret));
    }

    /* free. */
    if (send_pbuf != NULL) {
      pbuf_free(send_pbuf);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  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;
}
/* Send PacketIn packet. */
lagopus_result_t
ofp_packet_in_handle(struct packet_in *packet_in,
                     uint64_t dpid) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct pbuf *send_pbuf = NULL;

  if (packet_in != NULL && packet_in->data != NULL) {
    /* PacketIn. */
    ret = ofp_packet_in_create(packet_in, &send_pbuf);

    if (ret == LAGOPUS_RESULT_OK) {
      ret = ofp_role_channel_write(send_pbuf, dpid,
                                   OFPT_PACKET_IN,
                                   packet_in->ofp_packet_in.reason);
      if (ret != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("Socket write error (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("FAILED (%s).\n",
                          lagopus_error_get_string(ret));
    }
  } else {
    lagopus_msg_warning("Arg is NULL.\n");
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  /* free. */
  if (send_pbuf != NULL) {
    pbuf_free(send_pbuf);
  }

  return ret;
}
Esempio n. 4
0
/* Group mod received. */
lagopus_result_t
ofp_group_mod_handle(struct channel *channel, struct pbuf *pbuf,
                     struct ofp_header *xid_header,
                     struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  uint64_t dpid;
  struct ofp_group_mod group_mod;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    /* Parse group_mod header. */
    res = ofp_group_mod_decode(pbuf, &(group_mod));
    if (res == LAGOPUS_RESULT_OK) {
      /* check type */
      res = s_group_type_check(group_mod.type, error);
      if (res == LAGOPUS_RESULT_OK) {
        /* exec group_mod command. */
        dpid = channel_dpid_get(channel);
        switch (group_mod.command) {
          case OFPGC_ADD:
            res = s_ofpgc_add(pbuf, dpid,
                              &group_mod, error);
            break;
          case OFPGC_MODIFY:
            res = s_ofpgc_modify(pbuf, dpid,
                                 &group_mod, error);
            break;
          case OFPGC_DELETE:
            res = s_ofpgc_delete(pbuf, dpid,
                                 &group_mod, error);
            break;
          default:
            lagopus_msg_warning("unknown group_mod command.\n");
            ofp_error_set(error, OFPET_GROUP_MOD_FAILED, OFPGMFC_BAD_COMMAND);
            res = LAGOPUS_RESULT_OFP_ERROR;
            break;
        }
      }

      if (res != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("FAILED (%s).\n",
                            lagopus_error_get_string(res));
      }
    } else {
      lagopus_msg_warning("group_mod decode error (%s)\n",
                          lagopus_error_get_string(res));
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      res = LAGOPUS_RESULT_OFP_ERROR;
    }
  } else {
    /* params are NULL */
    res = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return res;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
lagopus_result_t
ofp_header_packet_set(struct channel *channel,
                      struct pbuf *pbuf) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  uint16_t cur_length;
  pbuf_info_t cur_pbuf_info;
  pbuf_info_t update_pbuf_info;
  struct ofp_header header;

  if (channel != NULL && pbuf != NULL) {
    /* Store current pbuf info. */
    pbuf_info_store(pbuf, &cur_pbuf_info);
    ret = pbuf_length_get(pbuf, &cur_length);

    if (ret == LAGOPUS_RESULT_OK) {
      /* Update pbuf info for ofp_header_decode_sneak. */
      pbuf_getp_set(&update_pbuf_info, pbuf_data_get(pbuf));
      pbuf_putp_set(&update_pbuf_info,
                    pbuf_data_get(pbuf) + sizeof(struct ofp_header));
      pbuf_plen_set(&update_pbuf_info, sizeof(struct ofp_header));
      pbuf_info_load(pbuf, &update_pbuf_info);

      ret = ofp_header_decode_sneak(pbuf, &header);
      if (ret == LAGOPUS_RESULT_OK) {
        /* Update pbuf info for ofp_header_create. */
        pbuf_reset(pbuf);
        pbuf_plen_set(pbuf, (size_t) cur_length);

        ret = ofp_header_create(channel, header.type, NULL,
                                &header, pbuf);
        if (ret == LAGOPUS_RESULT_OK) {
          /* Load pbuf info. */
          pbuf_info_load(pbuf, &cur_pbuf_info);
        } 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("FAILED (%s).\n",
                          lagopus_error_get_string(ret));
    }
  } else {
    return LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
lagopus_result_t
ofp_meter_features_request_handle(struct channel *channel,
                                  struct pbuf *pbuf,
                                  struct ofp_header *xid_header,
                                  struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  uint64_t dpid;
  struct ofp_meter_features ofp_meter_features;
  struct pbuf_list *send_pbuf_list = NULL;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    if (pbuf_plen_equal_check(pbuf, 0) == LAGOPUS_RESULT_OK) {
      /* get datas */
      memset(&ofp_meter_features, 0, sizeof(ofp_meter_features));
      dpid = channel_dpid_get(channel);
      res = ofp_meter_features_get(dpid, &ofp_meter_features, error);
      if (res == LAGOPUS_RESULT_OK) {
        /* create desc reply. */
        res = ofp_meter_features_reply_create(channel,
                                              &send_pbuf_list,
                                              &ofp_meter_features,
                                              xid_header);
        if (res == LAGOPUS_RESULT_OK) {
          /* send desc reply */
          res = channel_send_packet_list(channel, send_pbuf_list);
          if (res != LAGOPUS_RESULT_OK) {
            lagopus_msg_warning("Socket write error (%s).\n",
                                lagopus_error_get_string(res));
          }
        } else {
          lagopus_msg_warning("reply creation failed, (%s).\n",
                              lagopus_error_get_string(res));
        }
        /* free. */
        if (send_pbuf_list != NULL) {
          pbuf_list_free(send_pbuf_list);
        }
      }
    } else {
      lagopus_msg_warning("over packet length.\n");
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      res = LAGOPUS_RESULT_OFP_ERROR;
    }
  } else {
    res = LAGOPUS_RESULT_INVALID_ARGS;
  }
  return res;
}
Esempio n. 8
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;
}
/* Group Features Request packet receive. */
lagopus_result_t
ofp_group_features_request_handle(struct channel *channel, struct pbuf *pbuf,
                                  struct ofp_header *xid_header,
                                  struct ofp_error *error) {
  lagopus_result_t ret;
  uint64_t dpid;
  struct ofp_group_features group_features;
  struct pbuf_list *pbuf_list = NULL;

  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    if (pbuf_plen_equal_check(pbuf, 0) == LAGOPUS_RESULT_OK) {
      dpid = channel_dpid_get(channel);

      ret = ofp_group_features_get(dpid,
                                   &group_features,
                                   error);
      if (ret == LAGOPUS_RESULT_OK) {
        ret = ofp_group_features_reply_create(channel, &pbuf_list,
                                              &group_features,
                                              xid_header);
        if (ret == LAGOPUS_RESULT_OK) {
          /* write packets. */
          ret = channel_send_packet_list(channel, pbuf_list);
          if (ret != LAGOPUS_RESULT_OK) {
            lagopus_msg_warning("Can't write\n");
          }
        } 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("over packet length.\n");
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      ret = LAGOPUS_RESULT_OFP_ERROR;
    }

    /* free. */
    if (pbuf_list != NULL) {
      pbuf_list_free(pbuf_list);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 10
0
static lagopus_result_t
s_parse_bucket_list(struct pbuf *pbuf,
                    struct bucket_list *bucket_list,
                    struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_OK;
  if (TAILQ_EMPTY(bucket_list) == true && pbuf_plen_get(pbuf) == 0) {
    res = LAGOPUS_RESULT_OK;    /* bucket_list is empty */
  } else {
    /* decode buckets. */
    while (pbuf_plen_get(pbuf) > 0) {
      res = ofp_bucket_parse(pbuf, bucket_list, error);
      if (res != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("FAILED : ofp_bucket_parse (%s).\n",
                            lagopus_error_get_string(res));
        break;
      }
    }
    /* check plen. */
    if (res == LAGOPUS_RESULT_OK && pbuf_plen_get(pbuf) > 0) {
      lagopus_msg_warning("packet decode failed. (size over).\n");
      ofp_error_set(error, OFPET_GROUP_MOD_FAILED,
                    OFPGMFC_BAD_BUCKET);
      res = LAGOPUS_RESULT_OFP_ERROR;
    }
  }
  return res;
}
Esempio n. 11
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;
}
Esempio n. 12
0
/* header only packet. */
lagopus_result_t
ofp_header_create(struct channel *channel, uint8_t type,
                  struct ofp_header *xid_header,
                  struct ofp_header *header,
                  struct pbuf *pbuf) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  uint32_t xid;

  if (channel != NULL && header != NULL &&
      pbuf != NULL) {
    if (xid_header != NULL) {
      xid = xid_header->xid;
    } else {
      xid = channel_xid_get(channel);
    }

    ofp_header_set(header, channel_version_get(channel), type,
                   (uint16_t) pbuf_plen_get(pbuf), xid);

    ret = ofp_header_encode(pbuf, header);
    if (ret != LAGOPUS_RESULT_OK) {
      lagopus_msg_warning("FAILED (%s).\n",
                          lagopus_error_get_string(ret));
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 13
0
bool
ofp_header_version_check(struct channel *channel,
                         struct ofp_header *header) {
  bool ret = false;
  uint8_t bridge_ofp_version;
  uint64_t dpid;

  if (channel != NULL && header != NULL) {
    dpid = channel_dpid_get(channel);
    ret = dpmgr_bridge_ofp_version_get(dpid, &bridge_ofp_version);

    if (ret == LAGOPUS_RESULT_OK) {
      if (bridge_ofp_version == header->version) {
        ret = true;
      } else {
        lagopus_msg_warning("Unsupported ofp version : %"PRIu8".\n",
                            header->version);
        ret = false;
      }
    } else {
      lagopus_msg_warning("FAILED (%s).\n",
                          lagopus_error_get_string(ret));
      ret = false;
    }
  } else {
    lagopus_msg_warning("Arg is NULL.\n");
    ret = false;
  }

  return ret;
}
Esempio n. 14
0
/* Table mod received. */
lagopus_result_t
ofp_table_mod_handle(struct channel *channel, struct pbuf *pbuf,
                     struct ofp_header *xid_header,
                     struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  uint64_t dpid;
  struct ofp_table_mod table_mod;

  /* check params */
  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL && error != NULL) {
    /* Parse table_mod header. */
    res = ofp_table_mod_decode(pbuf, &(table_mod));
    if (res != LAGOPUS_RESULT_OK) {
      lagopus_msg_warning("table_mod decode error.\n");
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      res = LAGOPUS_RESULT_OFP_ERROR;
    } else if (pbuf_plen_get(pbuf) > 0) {
      lagopus_msg_warning("packet decode failed. (size over).\n");
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      res = LAGOPUS_RESULT_OFP_ERROR;
    } else {                    /* decode success */
      /* dump trace. */
      table_mod_trace(&table_mod);

      /* check flag. */
      res = ofp_table_mod_config_check(table_mod.config, error);

      if (res == LAGOPUS_RESULT_OK) {
        dpid = channel_dpid_get(channel);
        /* set table_mod */
        res = ofp_table_mod_set(dpid, &table_mod, error);
        if (res != LAGOPUS_RESULT_OK) {
          lagopus_msg_warning("FAILED (%s).\n",
                              lagopus_error_get_string(res));
        }
      } else {
        lagopus_msg_warning("FAILED (%s).\n",
                            lagopus_error_get_string(res));
      }
    }
  } else {
    res = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return res;
}
Esempio n. 15
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;
}
Esempio n. 16
0
lagopus_result_t
ofp_header_length_set(struct pbuf *pbuf,
                      uint16_t length) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  pbuf_info_t cur_pbuf_info;
  pbuf_info_t update_pbuf_info;
  struct ofp_header header;

  if (pbuf != NULL) {
    /* Store current pbuf info. */
    pbuf_info_store(pbuf, &cur_pbuf_info);

    /* Update pbuf info for ofp_header_decode_sneak. */
    pbuf_getp_set(&update_pbuf_info, pbuf_data_get(pbuf));
    pbuf_putp_set(&update_pbuf_info,
                  pbuf_data_get(pbuf) + sizeof(struct ofp_header));
    pbuf_plen_set(&update_pbuf_info, sizeof(struct ofp_header));
    pbuf_info_load(pbuf, &update_pbuf_info);

    ret = ofp_header_decode_sneak(pbuf, &header);
    if (ret == LAGOPUS_RESULT_OK) {
      /* Set length.*/
      header.length = length;
      /* Update pbuf info for ofp_header_encode. */
      pbuf_reset(pbuf);
      pbuf_plen_set(pbuf, sizeof(struct ofp_header));

      ret = ofp_header_encode(pbuf, &header);
      if (ret == LAGOPUS_RESULT_OK) {
        /* Load pbuf info. */
        pbuf_info_load(pbuf, &cur_pbuf_info);
      } 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 {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 17
0
static void
s_destroy_channel(struct channel *channel) {
  if (channel != NULL) {
    lagopus_result_t ret;
    ret = channel_free(channel);
    if (ret != LAGOPUS_RESULT_OK) {
      lagopus_msg_fatal("channel_free error (%s)\n",
                        lagopus_error_get_string(ret));
    }
  }
}
Esempio n. 18
0
/* Header only packet receive. */
lagopus_result_t
ofp_header_handle(struct channel *channel, struct pbuf *pbuf,
                  struct ofp_error *error) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct ofp_header msg;

  if (channel != NULL && pbuf != NULL &&
      error != NULL) {
    /* Parse ofp_header. */
    ret = ofp_header_decode(pbuf, &msg);
    if (ret == LAGOPUS_RESULT_OK) {
      /* Skip payload if it exists. */
      if (pbuf_plen_get(pbuf) > 0) {
        ret = pbuf_forward(pbuf, pbuf_plen_get(pbuf));
        if (ret != LAGOPUS_RESULT_OK) {
          lagopus_msg_warning("FAILED (%s).\n",
                              lagopus_error_get_string(ret));
          if (ret == LAGOPUS_RESULT_OUT_OF_RANGE) {
            ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
            ret = LAGOPUS_RESULT_OFP_ERROR;
          }
        }
      }

      if (ret == LAGOPUS_RESULT_OK &&
          channel_version_get(channel) != msg.version) {
        lagopus_msg_warning("Unsupported vetsion.\n");
        ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION);
        ret = LAGOPUS_RESULT_OFP_ERROR;
      }
    } else {
      lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret));
      ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
      return LAGOPUS_RESULT_OFP_ERROR;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 19
0
lagopus_result_t
check_packet_parse_array_expect_error(ofp_handler_proc_t handler_proc,
                                      const char *packet[],
                                      int array_len,
                                      const struct ofp_error *expected_error) {

  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  struct channel *channel = create_data_channel();
  struct ofp_header xid_header;
  struct pbuf *pbuf;
  struct ofp_error error;
  bool error_has_occurred = false;
  int i;
  for (i = 0; i < array_len; i++) {
    lagopus_msg_debug(1, "packet[%d] start ... %s\n", i, packet[i]);
    /* create packet */
    create_packet(packet[i], &pbuf);
    /* parse header */
    if (ofp_header_decode_sneak_test(pbuf, &xid_header) !=
        LAGOPUS_RESULT_OK) {
      pbuf_free(pbuf);
      s_destroy_static_data();
      TEST_FAIL_MESSAGE("handler_test_utils.c: cannot decode header\n");
      return LAGOPUS_RESULT_OFP_ERROR;
    }
    /* call func & check */
    res = (handler_proc)(channel, pbuf, &xid_header, &error);
    lagopus_msg_debug(1, "packet[%d] done ... %s\n", i,
                      lagopus_error_get_string(res));
    if (res == LAGOPUS_RESULT_OK) {
      TEST_ASSERT_EQUAL_MESSAGE(0, pbuf->plen,
                                "handler_test_utils.c: packet data len error.");
    } else if (res == LAGOPUS_RESULT_OFP_ERROR) {
      error_has_occurred = true;
      if (expected_error != NULL) {
        TEST_ASSERT_EQUAL_OFP_ERROR(expected_error, &error);
      }
      pbuf_free(pbuf);
      break;
    }
    /* free */
    pbuf_free(pbuf);
  }

  /* free */
  s_destroy_static_data();

  if (error_has_occurred == true) {
    TEST_ASSERT_EQUAL_OFP_ERROR(expected_error, &error);
  }

  return res;
}
Esempio n. 20
0
static lagopus_result_t
features_reply_features_get(struct channel *channel,
                            struct ofp_switch_features *features) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  datastore_bridge_info_t info;
  size_t i;

  /* set ids/reserved. */
  features->datapath_id = channel_dpid_get(channel);
  features->auxiliary_id = channel_auxiliary_id_get(channel);
  features->reserved = 0;

  if ((ret = ofp_bridgeq_mgr_info_get(features->datapath_id,
                                      &info)) !=
      LAGOPUS_RESULT_OK) {
    lagopus_msg_warning("FAILED (%s).\n",
                        lagopus_error_get_string(ret));
    goto done;
  }

  /* set max. */
  features->n_buffers = info.max_buffered_packets;
  features->n_tables = info.max_tables;

  /* set capabilities. */
  features->capabilities = 0;
  for (i = 0; i < capabilities_size; i++) {
    if ((ret = features_reply_features_capability_set(
            info.capabilities,
            i,
            &features->capabilities)) != LAGOPUS_RESULT_OK) {
      lagopus_msg_warning("FAILED (%s).\n",
                          lagopus_error_get_string(ret));
      goto done;
    }
  }

done:
  return ret;
}
Esempio n. 21
0
static lagopus_result_t
snmpmgr_thread_loop(const lagopus_thread_t *selfptr, void *arg) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  lagopus_chrono_t interval = DEFAULT_SNMPMGR_LOOP_INTERVAL_NSEC;
  global_state_t global_state;
  shutdown_grace_level_t l;
  (void)selfptr;
  (void)arg;

  /* open the session to AgentX master agent here. */
  init_snmp(SNMP_TYPE);

  /* wait all modules start */
  if ((ret = global_state_wait_for(GLOBAL_STATE_STARTED,
                                   &global_state, &l,
                                   -1 /* forever! */)) !=
      LAGOPUS_RESULT_OK) {
    lagopus_perror(ret);
  } else {
    if (global_state != GLOBAL_STATE_STARTED) {
      lagopus_exit_fatal("must not happen. die!\n");
    }
  }

  /* all modules have started, then send a coldStart trap */
  (void)send_coldStart_trap();

  lagopus_msg_info("SNMP manager started (as a thread).\n");

  /* main loop */
  while (keep_running) {
    (void)lagopus_mutex_lock(&snmp_lock);
    ret = internal_snmpmgr_poll(interval);
    (void)lagopus_mutex_unlock(&snmp_lock);
    if (ret != LAGOPUS_RESULT_OK && ret != LAGOPUS_RESULT_TIMEDOUT) {
      lagopus_msg_warning("failed to poll SNMP AgentX request: %s",
                          lagopus_error_get_string(ret));
    }
    check_status_and_send_traps();
  }

  /* stop SNMP */
  snmp_shutdown(SNMP_TYPE);

  (void)lagopus_mutex_lock(&snmp_state_lock);
  if (state != SNMPMGR_RUNNABLE) {
    state = SNMPMGR_NONE;
  }
  (void)lagopus_mutex_unlock(&snmp_state_lock);

  return LAGOPUS_RESULT_OK;
}
Esempio n. 22
0
/* Desc Request packet receive. */
lagopus_result_t
ofp_desc_request_handle(struct channel *channel, struct pbuf *pbuf,
                        struct ofp_header *xid_header,
                        struct ofp_error *error) {
  lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES;
  uint64_t dpid;
  struct ofp_desc ofp_desc;
  struct pbuf_list *send_pbuf_list = NULL;

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

    /* get datas */
    memset(&ofp_desc, 0, sizeof(ofp_desc));
    res = ofp_desc_get(dpid, &ofp_desc, error);
    if (res == LAGOPUS_RESULT_OK) {
      /* create desc reply. */
      res = ofp_desc_reply_create(channel, &send_pbuf_list,
                                  &ofp_desc, xid_header);
      if (res == LAGOPUS_RESULT_OK) {
        /* send desc reply */
        res = channel_send_packet_list(channel, send_pbuf_list);
        if (res != LAGOPUS_RESULT_OK) {
          lagopus_msg_warning("Socket write error (%s).\n",
                              lagopus_error_get_string(res));
        }
      } else {
        lagopus_msg_warning("reply creation failed, (%s).\n",
                            lagopus_error_get_string(res));
      }
      pbuf_list_free(send_pbuf_list);
    }
  } else {
    res = LAGOPUS_RESULT_INVALID_ARGS;
  }
  return res;
}
/* Experimenter multipart packet receive. */
lagopus_result_t
ofp_experimenter_mp_request_handle(struct channel *channel, struct pbuf *pbuf,
                                   struct ofp_header *xid_header) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct pbuf_list *pbuf_list = NULL;
  struct ofp_experimenter_multipart_header exper_req;

  if (channel != NULL && pbuf != NULL &&
      xid_header != NULL) {
    /* Parse packet. */
    ret = ofp_experimenter_multipart_header_decode(pbuf, &exper_req);
    if (ret == LAGOPUS_RESULT_OK) {
      /* Experimenter request reply. */
      ret = ofp_experimenter_mp_reply_create(channel, &pbuf_list,
                                             xid_header, &exper_req);
      if (ret == LAGOPUS_RESULT_OK) {
        ret = channel_send_packet_list(channel, pbuf_list);
        if (ret != LAGOPUS_RESULT_OK) {
          lagopus_msg_warning("Can't write.\n");
          ret = LAGOPUS_RESULT_OFP_ERROR;
        }
      } 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;
    }

    /* free. */
    if (pbuf_list != NULL) {
      pbuf_list_free(pbuf_list);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
void
count_ifNumber(int32_t *ifNumber) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  size_t v;
  if (ifNumber != NULL) {
    struct port_stat *port_stat;
    if ((ret = dp_get_port_stat(&port_stat)) == LAGOPUS_RESULT_OK) {
      dataplane_count_ifNumber(port_stat, &v);
      *ifNumber = (int32_t)v;
      port_stat_release(port_stat);
      free(port_stat);
    } else {
      lagopus_msg_error("cannot count ports: %s\n",
                        lagopus_error_get_string(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;
}
Esempio n. 28
0
STATIC lagopus_result_t
ofp_port_status_create(struct port_status *port_status,
                       struct pbuf **pbuf) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  uint8_t tmp_version = 0x00;
  uint32_t tmp_xid = 0;

  if (port_status != NULL && pbuf != NULL) {
    /* alloc */
    *pbuf = pbuf_alloc(sizeof(struct ofp_port_status));
    if (pbuf != NULL) {
      pbuf_plen_set(*pbuf, sizeof(struct ofp_port_status));

      /* Fill in header. */
      /* tmp_* is replaced later. */
      ofp_header_set(&port_status->ofp_port_status.header,
                     tmp_version,
                     OFPT_PORT_STATUS,
                     sizeof(struct ofp_port_status),
                     tmp_xid);

      ret = ofp_port_status_encode(*pbuf, &port_status->ofp_port_status);
      if (ret != LAGOPUS_RESULT_OK) {
        lagopus_msg_warning("FAILED : ofp_port_status_encode (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("Can't allocate pbuf.\n");
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }

    /* free. */
    if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) {
      pbuf_free(*pbuf);
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Esempio n. 29
0
lagopus_result_t
ofp_set_async_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_async_config async_config;

    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_async_config_decode(pbuf, &async_config);
            if (ret == LAGOPUS_RESULT_OK) {
                /* dump trace. */
                set_async_trace(&async_config);

                /* Copy packet_in_mask, port_status_mask, flow_removed_mask. */
                channel_role_mask_set(channel, &async_config);
            } else {
                lagopus_msg_warning("FAILED : ofp_config_decode (%s).\n",
                                    lagopus_error_get_string(ret));
                ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
                ret = LAGOPUS_RESULT_OFP_ERROR;
            }
        } 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;
}
Esempio n. 30
0
/* SEND */
STATIC lagopus_result_t
ofp_packet_in_create(struct packet_in *packet_in,
                     struct pbuf **pbuf) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  uint16_t miss_send_len;
  uint16_t length = 0;
  uint16_t remain_length = 0;
  uint16_t match_total_len = 0;
  uint8_t tmp_version = 0x00;
  uint32_t tmp_xid = 0x00;
  uint16_t tmp_length = 0;

  if (packet_in != NULL && packet_in->data != NULL &&
      pbuf != NULL) {

    /* alloc */
    *pbuf = pbuf_alloc(OFP_PACKET_MAX_SIZE);

    if (*pbuf != NULL) {
      pbuf_plen_set(*pbuf, OFP_PACKET_MAX_SIZE);

      /* set total_len. */
      ret = pbuf_length_get(packet_in->data, &length);
      if (ret == LAGOPUS_RESULT_OK) {
        packet_in->ofp_packet_in.total_len = length;

        /* Fill in header. */
        /* tmp_* is replaced later. */
        ofp_header_set(&packet_in->ofp_packet_in.header, tmp_version,
                       OFPT_PACKET_IN, tmp_length, tmp_xid);

        ret = ofp_packet_in_encode(*pbuf, &packet_in->ofp_packet_in);

        if (ret == LAGOPUS_RESULT_OK) {
          ret = ofp_match_list_encode(NULL, *pbuf, &packet_in->match_list,
                                      &match_total_len);

          if (ret == LAGOPUS_RESULT_OK) {
            /* Cut packet. */
            remain_length = (uint16_t) pbuf_plen_get(*pbuf);
            if (packet_in->ofp_packet_in.buffer_id == OFP_NO_BUFFER) {
              miss_send_len = remain_length;
            } else {
              miss_send_len = packet_in->miss_send_len;
            }
            if (length < miss_send_len) {
              miss_send_len = length;
            }

            /* exist data */
            if (miss_send_len != 0) {
              /* add padding */
              ret = ofp_padding_add(*pbuf, OFP_PACKET_IN_PAD);

              if (ret == LAGOPUS_RESULT_OK) {
                /* Cut packet. (remain_length) */
                if (miss_send_len + OFP_PACKET_IN_PAD > remain_length) {
                  miss_send_len = remain_length;
                }

                if (pbuf_plen_check(*pbuf, miss_send_len) !=
                    LAGOPUS_RESULT_OK) {
                  lagopus_msg_warning("FAILED : over data length.\n");
                  ret = LAGOPUS_RESULT_OUT_OF_RANGE;
                } else {
                  /* copy data. */
                  ret = pbuf_copy_with_length(*pbuf, packet_in->data,
                                              miss_send_len);
                  if (ret == LAGOPUS_RESULT_OK) {
                    pbuf_plen_reset(*pbuf);
                  } else {
                    lagopus_msg_warning("FAILED (%s).\n",
                                        lagopus_error_get_string(ret));
                  }
                }
              } else {
                lagopus_msg_warning("FAILED : over padding length.\n");
              }
            } else {
              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("FAILED (%s).\n",
                            lagopus_error_get_string(ret));
      }
    } else {
      lagopus_msg_warning("Can't allocate pbuf.\n");
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }

    /* free. */
    if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) {
      pbuf_free(*pbuf);
      *pbuf = NULL;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}