int pff_nhop(struct pff * instance, struct pci * pci, port_id_t ** ports, size_t * count) { struct pff_ps *ps; if (!__pff_is_ok(instance)) return -1; if (!pci_is_ok(pci)) { LOG_ERR("Bogus PCI, cannot get NHOP"); return -1; } if (!ports || !count) { LOG_ERR("Bogus output parameters, won't get NHOP"); return -1; } rcu_read_lock(); ps = container_of(rcu_dereference(instance->base.ps), struct pff_ps, base); ASSERT(ps->pff_nhop); if (ps->pff_nhop(ps, pci, ports, count)) { rcu_read_unlock(); return -1; } rcu_read_unlock(); return 0; }
struct pci * pci_create_from_gfp(gfp_t flags, const void * data) { struct pci * tmp; if (!data) return NULL; tmp = rkmalloc(sizeof(*tmp), flags); if (!tmp) return NULL; if (!memcpy(tmp, data, sizeof(*tmp))) { rkfree(tmp); return NULL; } if (!pci_is_ok(tmp)) { LOG_ERR("Cannot create PCI from bad data"); rkfree(tmp); return NULL; } return tmp; }
int pdu_pci_set(struct pdu * pdu, struct pci * pci) { if (!pdu) return -1; if (!pci_is_ok(pci)) return -1; pdu->pci = pci; return 0; }
struct pci * pci_dup_gfp(gfp_t flags, const struct pci * pci) { struct pci * tmp; if (!pci_is_ok(pci)) return NULL; tmp = rkmalloc(sizeof(*tmp), flags); if (!tmp) return NULL; if (!memcpy(tmp, pci, sizeof(*tmp))) { rkfree(tmp); return NULL; } ASSERT(pci_is_ok(tmp)); return tmp; }
static int serialize_base_pci(const struct serdes * instance, char * data, const struct pci * pci, size_t pdu_len) { int offset; address_t addr; cep_id_t cep; qos_id_t qos; pdu_type_t type; pdu_flags_t flags; struct dt_cons * dt_cons; ASSERT(instance); ASSERT(data); ASSERT(pci_is_ok(pci)); ASSERT(pdu_len); dt_cons = instance->dt_cons; ASSERT(dt_cons); /* * Putting 1 as version number for now * If another version is needed, this will have to change * Always 8 bit long */ offset = 0; memcpy(data + offset, &version, VERSION_SIZE); offset += VERSION_SIZE; LOG_DBG("Serialized version %d, with size %d", version, VERSION_SIZE); addr = pci_destination(pci); memcpy(data + offset, &addr, dt_cons->address_length); offset += dt_cons->address_length; addr = pci_source(pci); memcpy(data + offset, &addr, dt_cons->address_length); offset += dt_cons->address_length; qos = pci_qos_id(pci); memcpy(data + offset, &qos, dt_cons->qos_id_length); offset += dt_cons->qos_id_length; cep = pci_cep_source(pci); memcpy(data + offset, &cep, dt_cons->cep_id_length); offset += dt_cons->cep_id_length; cep = pci_cep_destination(pci); memcpy(data + offset, &cep, dt_cons->cep_id_length); offset += dt_cons->cep_id_length; type = pci_type(pci); memcpy(data + offset, &type, PDU_TYPE_SIZE); offset += PDU_TYPE_SIZE; flags = pci_flags_get(pci); memcpy(data + offset, &flags, FLAGS_SIZE); offset += FLAGS_SIZE; memcpy(data + offset, &pdu_len, dt_cons->length_length); offset += dt_cons->length_length; return 0; }
bool pdu_is_ok(const struct pdu * p) { return (p && pci_is_ok(p->pci) && buffer_is_ok(p->buffer)) ? true : false; }
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; }