コード例 #1
0
ファイル: ofl-structs-pack.c プロジェクト: CPqD/nox12oflib
size_t
ofl_structs_match_pack(struct ofl_match_header *src, struct ofp_match *dst, uint8_t* oxm_fields, enum byte_order order, struct ofl_exp *exp) {
    switch (src->type) {
        case (OFPMT_OXM): {
            struct ofl_match *m = (struct ofl_match *)src;
            struct ofpbuf *b = ofpbuf_new(0);
            int oxm_len;
            dst->type = htons(m->header.type);
            oxm_fields = (uint8_t*) &dst->oxm_fields;
            dst->length = htons(sizeof(struct ofp_match));
            if (src->length){
                if (order == HOST_ORDER)
                    oxm_len = oxm_put_match(b, m);
                else oxm_len = oxm_put_packet_match(b,m);
                memcpy(oxm_fields, (uint8_t*) ofpbuf_pull(b,oxm_len), oxm_len);
                dst->length = htons(oxm_len + ((sizeof(struct ofp_match )-4)));
                ofpbuf_delete(b);
                return ntohs(dst->length);
            }
            else return 0;
        }
        default: {
            if (exp == NULL || exp->match == NULL || exp->match->pack == NULL) {
                OFL_LOG_WARN(LOG_MODULE, "Trying to pack experimenter match, but no callback was given.");
                return -1;
            }
            return exp->match->pack(src, dst);
        }
    }
}
コード例 #2
0
ファイル: ofpbuf.c プロジェクト: cho4036/MyProject
/* Creates and returns a new ofpbuf with an initial capacity of 'size +
 * headroom' bytes, reserving the first 'headroom' bytes as headroom. */
struct ofpbuf *
ofpbuf_new_with_headroom(size_t size, size_t headroom)
{
    struct ofpbuf *b = ofpbuf_new(size + headroom);
    ofpbuf_reserve(b, headroom);
    return b;
}
コード例 #3
0
ファイル: ofp.c プロジェクト: CPqD/ofsoftswitch13
/* Allocates and stores in '*bufferp' a new ofpbuf with a size of
 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
 * transaction id 'xid'.  Allocated bytes beyond the header, if any, are
 * zeroed.
 *
 * The caller is responsible for freeing '*bufferp' when it is no longer
 * needed.
 *
 * The OpenFlow header length is initially set to 'openflow_len'; if the
 * message is later extended, the length should be updated with
 * update_openflow_length() before sending.
 *
 * Returns the header. */
void *
make_openflow_xid(size_t openflow_len, uint8_t type, uint32_t xid,
                  struct ofpbuf **bufferp)
{
    *bufferp = ofpbuf_new(openflow_len);
    return put_openflow_xid(openflow_len, type, xid, *bufferp);
}
コード例 #4
0
ファイル: ofpbuf.c プロジェクト: CPqD/of11softswitch
struct ofpbuf *
ofpbuf_clone_data(const void *data, size_t size)
{
    struct ofpbuf *b = ofpbuf_new(size);
    ofpbuf_put(b, data, size);
    return b;
}
コード例 #5
0
static int
stream_recv(struct vconn *vconn, struct ofpbuf **bufferp)
{
    struct stream_vconn *s = stream_vconn_cast(vconn);
    struct ofpbuf *rx;
    size_t want_bytes;
    ssize_t retval;

    if (s->rxbuf == NULL) {
        s->rxbuf = ofpbuf_new(1564);
    }
    rx = s->rxbuf;

again:
    if (sizeof(struct ofp_header) > rx->size) {
        want_bytes = sizeof(struct ofp_header) - rx->size;
    } else {
        struct ofp_header *oh = rx->data;
        size_t length = ntohs(oh->length);
        if (length < sizeof(struct ofp_header)) {
            VLOG_ERR_RL(LOG_MODULE, &rl, "received too-short ofp_header (%zu bytes)",
                        length);
            return EPROTO;
        }
        want_bytes = length - rx->size;
        if (!want_bytes) {
            *bufferp = rx;
            s->rxbuf = NULL;
            return 0;
        }
    }
    ofpbuf_prealloc_tailroom(rx, want_bytes);

    retval = read(s->fd, ofpbuf_tail(rx), want_bytes);
    if (retval > 0) {
        rx->size += retval;
        if (retval == want_bytes) {
            if (rx->size > sizeof(struct ofp_header)) {
                *bufferp = rx;
                s->rxbuf = NULL;
                return 0;
            } else {
                goto again;
            }
        }
        return EAGAIN;
    } else if (retval == 0) {
        if (rx->size) {
            VLOG_ERR_RL(LOG_MODULE, &rl, "connection dropped mid-packet");
            return EPROTO;
        } else {
            return EOF;
        }
    } else {
        return errno;
    }
}
コード例 #6
0
ファイル: ofl-structs-unpack.c プロジェクト: CPqD/nox13oflib
static ofl_err
ofl_structs_oxm_match_unpack(struct ofp_match* src, uint8_t* buf, size_t *len, struct ofl_match **dst){

     int error = 0;
     struct ofpbuf *b = ofpbuf_new(0);
     struct ofl_match *m = (struct ofl_match *) malloc(sizeof(struct ofl_match));
     m->header.type = ntohs(src->type);
    *len -= ROUND_UP(ntohs(src->length),8);
     if(ntohs(src->length) > sizeof(struct ofp_match)){
         ofpbuf_put(b, buf, ntohs(src->length) - (sizeof(struct ofp_match) -4)); 
         error = oxm_pull_match(b, m, ntohs(src->length) - (sizeof(struct ofp_match) -4));
         m->header.length = ntohs(src->length) - 4;
     }
    else m->header.length = 0;
    ofpbuf_delete(b);    
    *dst = m;
    return error;
}
コード例 #7
0
ファイル: packets.c プロジェクト: andychenzy/dpdk-ovs
/* Converts hex digits in 'hex' to an Ethernet packet in '*packetp'.  The
 * caller must free '*packetp'.  On success, returns NULL.  On failure, returns
 * an error message and stores NULL in '*packetp'. */
const char *
eth_from_hex(const char *hex, struct ofpbuf **packetp)
{
    struct ofpbuf *packet;

    packet = *packetp = ofpbuf_new(strlen(hex) / 2);

    if (ofpbuf_put_hex(packet, hex, NULL)[0] != '\0') {
        ofpbuf_delete(packet);
        *packetp = NULL;
        return "Trailing garbage in packet data";
    }

    if (packet->size < ETH_HEADER_LEN) {
        ofpbuf_delete(packet);
        *packetp = NULL;
        return "Packet data too short for Ethernet";
    }

    return NULL;
}
コード例 #8
0
/* Sends 'request' to the kernel via 'sock' and waits for a response.  If
 * successful, returns 0.  On failure, returns a positive errno value.
 *
 * If 'replyp' is nonnull, then on success '*replyp' is set to the kernel's
 * reply, which the caller is responsible for freeing with ofpbuf_delete(), and
 * on failure '*replyp' is set to NULL.  If 'replyp' is null, then the kernel's
 * reply, if any, is discarded.
 *
 * Before the message is sent, nlmsg_len in 'request' will be finalized to
 * match msg->size, nlmsg_pid will be set to 'sock''s pid, and nlmsg_seq will
 * be initialized, NLM_F_ACK will be set in nlmsg_flags.
 *
 * The caller is responsible for destroying 'request'.
 *
 * Bare Netlink is an unreliable transport protocol.  This function layers
 * reliable delivery and reply semantics on top of bare Netlink.
 *
 * In Netlink, sending a request to the kernel is reliable enough, because the
 * kernel will tell us if the message cannot be queued (and we will in that
 * case put it on the transmit queue and wait until it can be delivered).
 *
 * Receiving the reply is the real problem: if the socket buffer is full when
 * the kernel tries to send the reply, the reply will be dropped.  However, the
 * kernel sets a flag that a reply has been dropped.  The next call to recv
 * then returns ENOBUFS.  We can then re-send the request.
 *
 * Caveats:
 *
 *      1. Netlink depends on sequence numbers to match up requests and
 *         replies.  The sender of a request supplies a sequence number, and
 *         the reply echos back that sequence number.
 *
 *         This is fine, but (1) some kernel netlink implementations are
 *         broken, in that they fail to echo sequence numbers and (2) this
 *         function will drop packets with non-matching sequence numbers, so
 *         that only a single request can be usefully transacted at a time.
 *
 *      2. Resending the request causes it to be re-executed, so the request
 *         needs to be idempotent.
 */
int
nl_sock_transact(struct nl_sock *sock, const struct ofpbuf *request,
                 struct ofpbuf **replyp)
{
    struct nl_transaction *transactionp;
    struct nl_transaction transaction;

    transaction.request = CONST_CAST(struct ofpbuf *, request);
    transaction.reply = replyp ? ofpbuf_new(1024) : NULL;
    transactionp = &transaction;

    nl_sock_transact_multiple(sock, &transactionp, 1);

    if (replyp) {
        if (transaction.error) {
            ofpbuf_delete(transaction.reply);
            *replyp = NULL;
        } else {
            *replyp = transaction.reply;
        }
    }

    return transaction.error;
}
コード例 #9
0
ファイル: ofl-structs-pack.c プロジェクト: zoh90/openflow1.3
size_t
ofl_structs_match_pack(struct ofl_match_header *src, struct ofp_match *dst, uint8_t* oxm_fields, struct ofl_exp *exp) {
    switch (src->type) {
        case (OFPMT_OXM): {
            struct ofl_match *m = (struct ofl_match *)src;
            struct ofpbuf *b = ofpbuf_new(0);
            int oxm_len;
            dst->type = htons(m->header.type);
            oxm_fields = (uint8_t*) &dst->oxm_fields;
            dst->length = htons(sizeof(struct ofp_match) - 4);
            if (src->length){
                oxm_len = oxm_put_match(b, m);
                memcpy(oxm_fields, (uint8_t*) ofpbuf_pull(b,oxm_len), oxm_len);
                dst->length = htons(oxm_len + ((sizeof(struct ofp_match )-4)));
                ofpbuf_delete(b);
                return ntohs(dst->length);
            }
            else return 0;
        }
//***********************************
// Modified by Bence Ladoczki
        //case (OFPMT_STANDARD): {
            //struct ofl_match_standard *m = (struct ofl_match_standard *)src;
//
            //dst->type =          htons( m->header.type);
            //dst->length =        htons( OFPMT_STANDARD_LENGTH);
            //dst->in_port =       htonl( m->in_port);
            //dst->wildcards =     htonl( m->wildcards);
            //memcpy(&(dst->dl_src),      &(m->dl_src),      OFP_ETH_ALEN);
            //memcpy(&(dst->dl_src_mask), &(m->dl_src_mask), OFP_ETH_ALEN);
            //memcpy(&(dst->dl_dst),      &(m->dl_dst),      OFP_ETH_ALEN);
            //memcpy(&(dst->dl_dst_mask), &(m->dl_dst_mask), OFP_ETH_ALEN);
            //dst->dl_vlan =       htons( m->dl_vlan);
            //dst->dl_vlan_pcp =          m->dl_vlan_pcp;
            //memset(dst->pad1, 0x00, 1);
            //dst->dl_type =       htons( m->dl_type);
            //dst->nw_tos =               m->nw_tos;
            //dst->nw_proto =             m->nw_proto;
            //dst->nw_src =               m->nw_src;
            //dst->nw_src_mask =          m->nw_src_mask;
            //dst->nw_dst =               m ->nw_dst;
            //dst->nw_dst_mask =          m->nw_dst_mask;
            //dst->tp_src =        htons( m->tp_src);
            //dst->tp_dst =        htons( m->tp_dst);
            //dst->mpls_label =    htonl( m->mpls_label);
            //dst->mpls_tc =              m->mpls_tc;
            //memset(dst->pad2, 0x00, 3);
            //dst->metadata =      hton64(m->metadata);
            //dst->metadata_mask = hton64(m->metadata_mask);
//
            //return sizeof(struct ofp_match);
        //}
//***********************************

        default: {
            if (exp == NULL || exp->match == NULL || exp->match->pack == NULL) {
    OFL_LOG_WARN(LOG_MODULE, "Setting leak logging file size limit to %"PRIdMAX" bytes", src->type);
                OFL_LOG_WARN(LOG_MODULE, "Trying to pack experimenter match, but no callback was given.");
                return -1;
            }
            return exp->match->pack(src, dst);
        }
    }
}
コード例 #10
0
ファイル: ofp.c プロジェクト: CPqD/ofsoftswitch13
/* Allocates and stores in '*bufferp' a new ofpbuf with a size of
 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
 * an arbitrary transaction id.  Allocated bytes beyond the header, if any, are
 * zeroed.
 *
 * The caller is responsible for freeing '*bufferp' when it is no longer
 * needed.
 *
 * The OpenFlow header length is initially set to 'openflow_len'; if the
 * message is later extended, the length should be updated with
 * update_openflow_length() before sending.
 *
 * Returns the header. */
void *
make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **bufferp)
{
    *bufferp = ofpbuf_new(openflow_len);
    return put_openflow_xid(openflow_len, type, alloc_xid(), *bufferp);
}
コード例 #11
0
ファイル: ofp.c プロジェクト: CPqD/ofsoftswitch13
void
update_instruction_length(struct ofpbuf *buffer, size_t oia_offset)
{
    struct ofp_header *oh = ofpbuf_at_assert(buffer, 0, sizeof *oh);
    struct ofp_instruction *ih = ofpbuf_at_assert(buffer, oia_offset,
						  sizeof *ih);
    ih->len = htons(buffer->size - oia_offset);
}

struct ofpbuf *
make_flow_mod(uint8_t command, uint8_t table_id,
	      const struct flow *flow UNUSED, size_t actions_len)
{
    struct ofp_flow_mod *ofm;
    size_t size = sizeof *ofm + actions_len;
    struct ofpbuf *out = ofpbuf_new(size);
    ofm = ofpbuf_put_zeros(out, sizeof *ofm);
    ofm->header.version = OFP_VERSION;
    ofm->header.type = OFPT_FLOW_MOD;
    ofm->header.length = htons(size);
    ofm->cookie = 0;
    /*TODO fill match
    ofm->match.in_port = flow->in_port;
    memcpy(ofm->match.dl_src, flow->dl_src, sizeof ofm->match.dl_src);
    memcpy(ofm->match.dl_dst, flow->dl_dst, sizeof ofm->match.dl_dst);
    ofm->match.dl_vlan = flow->dl_vlan;
    ofm->match.dl_vlan_pcp = flow->dl_vlan_pcp;
    ofm->match.dl_type = flow->dl_type;
    ofm->match.nw_src = flow->nw_src;
    ofm->match.nw_dst = flow->nw_dst;
    ofm->match.nw_proto = flow->nw_proto;
コード例 #12
0
static int
ssl_recv(struct vconn *vconn, struct ofpbuf **bufferp)
{
    struct ssl_vconn *sslv = ssl_vconn_cast(vconn);
    struct ofpbuf *rx;
    size_t want_bytes;
    int old_state;
    ssize_t ret;

    if (sslv->rxbuf == NULL) {
        sslv->rxbuf = ofpbuf_new(1564);
    }
    rx = sslv->rxbuf;

again:
    if (sizeof(struct ofp_header) > rx->size) {
        want_bytes = sizeof(struct ofp_header) - rx->size;
    } else {
        struct ofp_header *oh = rx->data;
        size_t length = ntohs(oh->length);
        if (length < sizeof(struct ofp_header)) {
            VLOG_ERR_RL(&rl, "received too-short ofp_header (%zu bytes)",
                        length);
            return EPROTO;
        }
        want_bytes = length - rx->size;
        if (!want_bytes) {
            *bufferp = rx;
            sslv->rxbuf = NULL;
            return 0;
        }
    }
    ofpbuf_prealloc_tailroom(rx, want_bytes);

    /* Behavior of zero-byte SSL_read is poorly defined. */
    assert(want_bytes > 0);

    old_state = SSL_get_state(sslv->ssl);
    ret = SSL_read(sslv->ssl, ofpbuf_tail(rx), want_bytes);
    if (old_state != SSL_get_state(sslv->ssl)) {
        sslv->tx_want = SSL_NOTHING;
        if (sslv->tx_waiter) {
            poll_cancel(sslv->tx_waiter);
            ssl_tx_poll_callback(sslv->fd, POLLIN, vconn);
        }
    }
    sslv->rx_want = SSL_NOTHING;

    if (ret > 0) {
        rx->size += ret;
        if (ret == want_bytes) {
            if (rx->size > sizeof(struct ofp_header)) {
                *bufferp = rx;
                sslv->rxbuf = NULL;
                return 0;
            } else {
                goto again;
            }
        }
        return EAGAIN;
    } else {
        int error = SSL_get_error(sslv->ssl, ret);
        if (error == SSL_ERROR_ZERO_RETURN) {
            /* Connection closed (EOF). */
            if (rx->size) {
                VLOG_WARN_RL(&rl, "SSL_read: unexpected connection close");
                return EPROTO;
            } else {
                return EOF;
            }
        } else {
            return interpret_ssl_error("SSL_read", ret, error, &sslv->rx_want);
        }
    }
}