示例#1
0
static int
default_transmission_control(struct dtp_ps * ps, struct pdu * pdu)
{
        struct dtp *  dtp = ps->dm;
        struct dt  *  dt;
        struct efcp * efcp;

        if (!dtp) {
                LOG_ERR("No instance passed, cannot run policy");
                pdu_destroy(pdu);
                return -1;
        }

        dt = dtp_dt(dtp);
        if (!dt) {
                LOG_ERR("Passed instance has no parent, cannot run policy");
                pdu_destroy(pdu);
                return -1;
        }

        efcp = dt_efcp(dt);
        if (!efcp) {
                LOG_ERR("Passed instance has no EFCP, cannot run policy");
                pdu_destroy(pdu);
                return -1;
        }

        /* Post SDU to RMT */
        LOG_DBG("defaultTxPolicy - sending to rmt");
        if (dtp_sv_max_seq_nr_set(dtp,
                                  pci_sequence_number_get(pdu_pci_get_ro(
                                                          pdu))))
                LOG_ERR("Problems setting max sequence number received "
                        "in default_transmission");

        LOG_DBG("local_soft_irq_pending: %d", local_softirq_pending());

        return common_efcp_pdu_send(efcp,
        			    dtp_rmt(dtp),
        			    pci_destination(pdu_pci_get_ro(pdu)),
        			    pci_qos_id(pdu_pci_get_ro(pdu)),
        		            pdu);
}
示例#2
0
文件: serdes.c 项目: msune/irati
/* Passing dt_cons already, for future work */
static int serialize_ctrl_seq(const struct serdes * instance,
                              char *                data,
                              const struct pci *    pci,
                              int                   offset)
{
        seq_num_t        seq;
        struct dt_cons * dt_cons;

        ASSERT(instance);
        ASSERT(data);
        ASSERT(pci);
        ASSERT(offset);

        dt_cons = instance->dt_cons;
        ASSERT(dt_cons);

        seq = pci_sequence_number_get(pci);
        memcpy(data + offset, &seq, CTRL_SEQ_NR);

        return 0;
}
示例#3
0
文件: dtcp.c 项目: shinrs20/stack
int dtcp_ack_flow_control_pdu_send(struct dtcp * dtcp, seq_num_t seq)
{
        struct pdu *   pdu;
        pdu_type_t     type;

        seq_num_t      dbg_seq_num;

        if (!dtcp) {
                LOG_ERR("No instance passed, cannot run policy");
                return -1;
        }

        atomic_inc(&dtcp->cpdus_in_transit);

        type = pdu_ctrl_type_get(dtcp, seq);
        if (!type) {
                atomic_dec(&dtcp->cpdus_in_transit);
                return 0;
        }

        pdu  = pdu_ctrl_generate(dtcp, type);
        if (!pdu) {
                atomic_dec(&dtcp->cpdus_in_transit);
                return -1;
        }

        dbg_seq_num = pci_sequence_number_get(pdu_pci_get_rw(pdu));

        LOG_DBG("DTCP Sending ACK (CPU: %d)", smp_processor_id());
        dump_we(dtcp, pdu_pci_get_rw(pdu));

        if (dtcp_pdu_send(dtcp, pdu)){
                atomic_dec(&dtcp->cpdus_in_transit);
                return -1;
        }

        atomic_dec(&dtcp->cpdus_in_transit);

        return 0;
}
示例#4
0
文件: dtcp.c 项目: shinrs20/stack
void dump_we(struct dtcp * dtcp, struct pci *  pci)
{
        struct dtp * dtp;
        seq_num_t    snd_rt_we;
        seq_num_t    snd_lf_we;
        seq_num_t    rcv_rt_we;
        seq_num_t    rcv_lf_we;
        seq_num_t    new_rt_we;
        seq_num_t    new_lf_we;
        seq_num_t    pci_seqn;
        seq_num_t    my_rt_we;
        seq_num_t    my_lf_we;
        seq_num_t    ack;

        ASSERT(dtcp);
        ASSERT(pci);

        dtp = dt_dtp(dtcp->parent);
        ASSERT(dtp);

        snd_rt_we = snd_rt_wind_edge(dtcp);
        snd_lf_we = dtcp_snd_lf_win(dtcp);
        rcv_rt_we = rcvr_rt_wind_edge(dtcp);
        rcv_lf_we = dt_sv_rcv_lft_win(dtcp->parent);
        new_rt_we = pci_control_new_rt_wind_edge(pci);
        new_lf_we = pci_control_new_left_wind_edge(pci);
        my_lf_we  = pci_control_my_left_wind_edge(pci);
        my_rt_we  = pci_control_my_rt_wind_edge(pci);
        pci_seqn  = pci_sequence_number_get(pci);
        ack       = pci_control_ack_seq_num(pci);

        LOG_DBG("SEQN: %u N/Ack: %u SndRWE: %u SndLWE: %u "
                "RcvRWE: %u RcvLWE: %u "
                "newRWE: %u newLWE: %u "
                "myRWE: %u myLWE: %u",
                pci_seqn, ack, snd_rt_we, snd_lf_we, rcv_rt_we, rcv_lf_we,
                new_rt_we, new_lf_we, my_rt_we, my_lf_we);
}
示例#5
0
文件: serdes.c 项目: msune/irati
static struct pdu_ser * pdu_serialize_gfp(gfp_t                       flags,
                                          const const struct serdes * instance,
                                          struct pdu *                pdu)
{
        struct pdu_ser *      tmp;
        struct dt_cons *      dt_cons;
        const void *          buffer_data;
        const struct buffer * buffer;
        const struct pci *    pci;
        size_t                size;
        ssize_t               buffer_size;
        ssize_t               pci_size;
        char *                data;
        pdu_type_t            pdu_type;
        seq_num_t             seq;
        struct buffer *       buf;

        if (!pdu_is_ok(pdu))
                return NULL;

        if (!instance)
                return NULL;

        dt_cons = instance->dt_cons;
        ASSERT(dt_cons);

        buffer = pdu_buffer_get_ro(pdu);
        if (!buffer)
                return NULL;

        buffer_data = buffer_data_ro(buffer);
        if (!buffer_data)
                return NULL;

        buffer_size = buffer_length(buffer);
        if (buffer_size <= 0)
                return NULL;

        pci = pdu_pci_get_ro(pdu);
        if (!pci)
                return NULL;

        pdu_type = pci_type(pci);
        if (!pdu_type_is_ok(pdu_type)) {
                LOG_ERR("Wrong PDU type");
                return NULL;
        }

        /* Base PCI size, fields present in all PDUs */
        pci_size = base_pci_size(dt_cons);

        /*
         * These are available in the stack at this point in time
         * Extend if necessary (e.g.) NACKs, SACKs, ...
         * Set size in first switch/case
         */
        switch (pdu_type) {
        case PDU_TYPE_MGMT:
        case PDU_TYPE_DT:
                size = pci_size + dt_cons->seq_num_length + buffer_size;
                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_FC:
                size = pci_size + CTRL_SEQ_NR + fc_pci_size(dt_cons);
                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_ACK:
                size = pci_size + CTRL_SEQ_NR + dt_cons->seq_num_length;
                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_ACK_AND_FC:
                size = pci_size +
                        CTRL_SEQ_NR +
                        fc_pci_size(dt_cons) +
                        dt_cons->seq_num_length;
                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_CC:
                size = pci_size +
                        2 * CTRL_SEQ_NR +
                        4 * dt_cons->seq_num_length +
                        RATE_LEN;
                if (size <= 0)
                        return NULL;

                break;
        default:
                LOG_ERR("Unknown PDU type %02X", pdu_type);
                return NULL;
        }

        data = rkmalloc(size, flags);
        if (!data)
                return NULL;

        /* Needed for all PDUs */
        if (serialize_base_pci(instance, data, pci, size)) {
                LOG_ERR("Failed to serialize base PCI");
                rkfree(data);
                return NULL;
        }

        /* Do actual serializing in the second switch case */
        switch (pdu_type) {
        case PDU_TYPE_MGMT:
        case PDU_TYPE_DT:
                seq = pci_sequence_number_get(pci);
                memcpy(data + pci_size, &seq, dt_cons->seq_num_length);

                memcpy(data + pci_size + dt_cons->seq_num_length,
                       buffer_data, buffer_size);

                break;
        case PDU_TYPE_FC:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_fc_pci(instance, data, pci,
                                     pci_size + CTRL_SEQ_NR)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        case PDU_TYPE_ACK:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_ack_pci(instance, data, pci,
                                      pci_size + CTRL_SEQ_NR)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        case PDU_TYPE_ACK_AND_FC:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_ack_pci(instance, data, pci,
                                      pci_size + CTRL_SEQ_NR) ||
                    serialize_fc_pci(instance, data, pci,
                                     pci_size +
                                     CTRL_SEQ_NR +
                                     dt_cons->seq_num_length)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        case PDU_TYPE_CC:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_cc_pci(instance, data, pci,
                                     pci_size + CTRL_SEQ_NR)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        default:
                LOG_ERR("Unknown PDU type %02X", pdu_type);
                return NULL;
        }

        buf = buffer_create_with_gfp(flags, data, size);
        if (!buf) {
                rkfree(data);
                return NULL;
        }

        tmp = pdu_ser_create_buffer_with_gfp(flags, buf);
        if (!tmp) {
                rkfree(buf);
                return NULL;
        }

        pdu_destroy(pdu);

        return tmp;
}
示例#6
0
文件: dtcp.c 项目: shinrs20/stack
int dtcp_common_rcv_control(struct dtcp * dtcp, struct pdu * pdu)
{
        struct dtcp_ps * ps;
        struct pci *     pci;
        pdu_type_t       type;
        seq_num_t        sn;
        seq_num_t        last_ctrl;
        int              ret;

        LOG_DBG("dtcp_common_rcv_control called");

        if (!pdu_is_ok(pdu)) {
                LOG_ERR("PDU is not ok");
                pdu_destroy(pdu);
                return -1;
        }

        if (!dtcp) {
                LOG_ERR("DTCP instance bogus");
                pdu_destroy(pdu);
                return -1;
        }

        atomic_inc(&dtcp->cpdus_in_transit);

        pci = pdu_pci_get_rw(pdu);
        if (!pci_is_ok(pci)) {
                LOG_ERR("PCI couldn't be retrieved");
                atomic_dec(&dtcp->cpdus_in_transit);
                pdu_destroy(pdu);
                return -1;
        }

        type = pci_type(pci);

        if (!pdu_type_is_control(type)) {
                LOG_ERR("CommonRCVControl policy received a non-control PDU");
                atomic_dec(&dtcp->cpdus_in_transit);
                pdu_destroy(pdu);
                return -1;
        }

        sn = pci_sequence_number_get(pci);
        last_ctrl = last_rcv_ctrl_seq(dtcp);

        if (sn <= last_ctrl) {
                switch (type) {
                case PDU_TYPE_FC:
                        flow_ctrl_inc(dtcp);
                        break;
                case PDU_TYPE_ACK:
                        acks_inc(dtcp);
                        break;
                case PDU_TYPE_ACK_AND_FC:
                        acks_inc(dtcp);
                        flow_ctrl_inc(dtcp);
                        break;
                default:
                        break;
                }

                pdu_destroy(pdu);
                return 0;

        }
        rcu_read_lock();
        ps = container_of(rcu_dereference(dtcp->base.ps),
                          struct dtcp_ps, base);
        if (sn > (last_ctrl + 1)) {
                ps->lost_control_pdu(ps);
        }
        rcu_read_unlock();

        /* We are in sn >= last_ctrl + 1 */

        last_rcv_ctrl_seq_set(dtcp, sn);

        LOG_DBG("dtcp_common_rcv_control sending to proper function...");

        switch (type) {
        case PDU_TYPE_ACK:
                ret = rcv_ack(dtcp, pdu);
                break;
        case PDU_TYPE_NACK:
                ret = rcv_nack_ctl(dtcp, pdu);
                break;
        case PDU_TYPE_FC:
                ret = rcv_flow_ctl(dtcp, pdu);
                break;
        case PDU_TYPE_ACK_AND_FC:
                ret = rcv_ack_and_flow_ctl(dtcp, pdu);
                break;
        default:
                ret = -1;
                break;
        }

        atomic_dec(&dtcp->cpdus_in_transit);
        return ret;
}
示例#7
0
文件: serdes.c 项目: shinrs20/stack
static struct pdu_ser * pdu_serialize_gfp(gfp_t                       flags,
                                          const const struct serdes * instance,
                                          struct pdu *                pdu,
                                          struct dup_config_entry   * dup_conf,
                                          struct crypto_blkcipher   * blkcipher)
{
        struct pdu_ser *      tmp;
        struct dt_cons *      dt_cons;
        const void *          buffer_data;
        const struct buffer * buffer;
        const struct pci *    pci;
        size_t                size;
        ssize_t               buffer_size;
        ssize_t               blk_size;
        ssize_t               encrypted_size;
        ssize_t               pci_size;
        char *                data;
        pdu_type_t            pdu_type;
        seq_num_t             seq;
        struct buffer *       buf;
        int i;

        if (!pdu_is_ok(pdu))
                return NULL;

        if (!instance)
                return NULL;

        dt_cons = instance->dt_cons;
        ASSERT(dt_cons);

        buffer = pdu_buffer_get_ro(pdu);
        if (!buffer)
                return NULL;

        buffer_data = buffer_data_ro(buffer);
        if (!buffer_data)
                return NULL;

        buffer_size = buffer_length(buffer);
        if (buffer_size <= 0)
                return NULL;

        pci = pdu_pci_get_ro(pdu);
        if (!pci)
                return NULL;

        pdu_type = pci_type(pci);
        if (!pdu_type_is_ok(pdu_type)) {
                LOG_ERR("Wrong PDU type");
                return NULL;
        }

        /* Base PCI size, fields present in all PDUs */
        pci_size = base_pci_size(dt_cons);

        /*
         * These are available in the stack at this point in time
         * Extend if necessary (e.g.) NACKs, SACKs, ...
         * Set size in first switch/case
         */
        switch (pdu_type) {
        case PDU_TYPE_MGMT:
        case PDU_TYPE_DT:
                size = pci_size + dt_cons->seq_num_length + buffer_size;

                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_FC:
                size = pci_size + CTRL_SEQ_NR + fc_pci_size(dt_cons);
                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_ACK:
                size = pci_size + CTRL_SEQ_NR + dt_cons->seq_num_length;
                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_ACK_AND_FC:
                size = pci_size +
                        CTRL_SEQ_NR +
                        fc_pci_size(dt_cons) +
                        dt_cons->seq_num_length;
                if (size <= 0)
                        return NULL;

                break;
        case PDU_TYPE_CACK:
                size = pci_size +
                        2 * CTRL_SEQ_NR +
                        4 * dt_cons->seq_num_length +
                        RATE_LEN;
                if (size <= 0)
                        return NULL;

                break;
        default:
                LOG_ERR("Unknown PDU type %02X", pdu_type);
                return NULL;
        }

        data = rkmalloc(size, flags);
        if (!data)
                return NULL;

        /* Needed for all PDUs */
        if (serialize_base_pci(instance, data, pci, size)) {
                LOG_ERR("Failed to serialize base PCI");
                rkfree(data);
                return NULL;
        }

        /* Do actual serializing in the second switch case */
        switch (pdu_type) {
        case PDU_TYPE_MGMT:
        case PDU_TYPE_DT:
                seq = pci_sequence_number_get(pci);
                memcpy(data + pci_size, &seq, dt_cons->seq_num_length);

                memcpy(data + pci_size + dt_cons->seq_num_length,
                       buffer_data, buffer_size);

                break;
        case PDU_TYPE_FC:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_fc_pci(instance, data, pci,
                                     pci_size + CTRL_SEQ_NR)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        case PDU_TYPE_ACK:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_ack_pci(instance, data, pci,
                                      pci_size + CTRL_SEQ_NR)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        case PDU_TYPE_ACK_AND_FC:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_ack_pci(instance, data, pci,
                                      pci_size + CTRL_SEQ_NR) ||
                    serialize_fc_pci(instance, data, pci,
                                     pci_size +
                                     CTRL_SEQ_NR +
                                     dt_cons->seq_num_length)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        case PDU_TYPE_CACK:
                if (serialize_ctrl_seq(instance, data, pci, pci_size) ||
                    serialize_cc_pci(instance, data, pci,
                                     pci_size + CTRL_SEQ_NR)) {
                        rkfree(data);
                        return NULL;
                }

                break;
        default:
                LOG_ERR("Unknown PDU type %02X", pdu_type);
                return NULL;
        }

        buf = buffer_create_with_gfp(flags, data, size);
        if (!buf) {
                rkfree(data);
                return NULL;
        }

        tmp = pdu_ser_create_buffer_with_gfp(flags, buf);
        if (!tmp) {
                rkfree(buf);
                return NULL;
        }

        /* FIXME: this should be moved to specific policy code */
        if (dup_conf != NULL && dup_conf->ttl_policy != NULL){
            if (pdu_ser_head_grow_gfp(flags, tmp, sizeof(u8))) {
                    LOG_ERR("Failed to grow ser PDU");
                    pdu_ser_destroy(tmp);
                    return NULL;
            }

            if (!dup_ttl_set(tmp, pci_ttl(pci))) {
                    LOG_ERR("Could not set TTL");
                    pdu_ser_destroy(tmp);
                    return NULL;
            }

            if (dup_ttl_is_expired(tmp)) {
                    LOG_DBG("TTL is expired, dropping PDU");
                    pdu_ser_destroy(tmp);
                    return NULL;
            }
        }

        /* FIXME: this should be moved to specific policy code */
        if (blkcipher != NULL && dup_conf != NULL
        		&& dup_conf->enable_encryption){
                buf = pdu_ser_buffer(tmp);
                blk_size = crypto_blkcipher_blocksize(blkcipher);
                buffer_size = buffer_length(buf);
                encrypted_size = (buffer_size/blk_size + 1) * blk_size;

                if (pdu_ser_tail_grow_gfp(tmp, encrypted_size - buffer_size)){
                    LOG_ERR("Failed to grow ser PDU");
                    pdu_ser_destroy(tmp);
                    return NULL;
                }

                /* PADDING */
                data = buffer_data_rw(buf);
                for (i=encrypted_size-1; i>buffer_size; i--){
                    data[i] = encrypted_size - buffer_size;
                }

                /* Encrypt */
                if (!dup_encrypt_data(tmp, blkcipher)) {
                	LOG_ERR("Failed to encrypt PDU");
                	pdu_ser_destroy(tmp);
                	return NULL;
                }
        }

        /* FIXME: this should be moved to specific policy code */
        if (dup_conf != NULL && dup_conf->error_check_policy != NULL){
            /* Assuming CRC32 */
            if (pdu_ser_head_grow_gfp(flags, tmp, sizeof(u32))) {
                    LOG_ERR("Failed to grow ser PDU");
                    pdu_ser_destroy(tmp);
                    return NULL;
            }

            if (!dup_chksum_set(tmp)) {
                    LOG_ERR("Failed to add CRC");
                    pdu_ser_destroy(tmp);
                    return NULL;
            }

            ASSERT(dup_chksum_is_ok(tmp));
        }

        return tmp;
}