eth_push_vlan(packet, htons(ETH_TYPE_VLAN), htons(tci));
}
- ccm = packet->l3;
+ ccm = ofpbuf_get_l3(packet);
ccm->mdlevel_version = 0;
ccm->opcode = CCM_OPCODE;
ccm->tlv_offset = 70;
ovs_mutex_lock(&mutex);
eth = p->l2;
- ccm = ofpbuf_at(p, (uint8_t *)p->l3 - (uint8_t *)p->data, CCM_ACCEPT_LEN);
+ ccm = ofpbuf_at(p, (uint8_t *)ofpbuf_get_l3(p) - (uint8_t *)p->data,
+ CCM_ACCEPT_LEN);
if (!ccm) {
VLOG_INFO_RL(&rl, "%s: Received an unparseable 802.1ag CCM heartbeat.",
/* Initializes 'flow' members from 'packet' and 'md'
*
- * Initializes 'packet' header pointers as follows:
+ * Initializes 'packet' header l2 pointer to the start of the Ethernet
+ * header, and the layer offsets as follows:
*
- * - packet->l2 to the start of the Ethernet header.
+ * - packet->l2_5_ofs to the start of the MPLS shim header, or UINT16_MAX
+ * when there is no MPLS shim header.
*
- * - packet->l2_5 to the start of the MPLS shim header.
- *
- * - packet->l3 to just past the Ethernet header, or just past the
+ * - packet->l3_ofs to just past the Ethernet header, or just past the
* vlan_header if one is present, to the first byte of the payload of the
- * Ethernet frame.
+ * Ethernet frame. UINT16_MAX if the frame is too short to contain an
+ * Ethernet header.
*
- * - packet->l4 to just past the IPv4 header, if one is present and has a
- * correct length, and otherwise NULL.
+ * - packet->l4_ofs to just past the IPv4 header, if one is present and
+ * has at least the content used for the fields of interest for the flow,
+ * otherwise UINT16_MAX.
*/
void
flow_extract(struct ofpbuf *packet, const struct pkt_metadata *md,
}
packet->l2 = b.data;
- packet->l2_5 = NULL;
- packet->l3 = NULL;
- packet->l4 = NULL;
+ ofpbuf_set_l2_5(packet, NULL);
+ ofpbuf_set_l3(packet, NULL);
+ ofpbuf_set_l4(packet, NULL);
if (b.size < sizeof *eth) {
return;
/* Parse mpls, copy l3 ttl. */
if (eth_type_mpls(flow->dl_type)) {
- packet->l2_5 = b.data;
+ ofpbuf_set_l2_5(packet, b.data);
parse_mpls(&b, flow);
}
/* Network layer. */
- packet->l3 = b.data;
+ ofpbuf_set_l3(packet, b.data);
if (flow->dl_type == htons(ETH_TYPE_IP)) {
const struct ip_header *nh = pull_ip(&b);
if (nh) {
- packet->l4 = b.data;
+ ofpbuf_set_l4(packet, b.data);
flow->nw_src = get_16aligned_be32(&nh->ip_src);
flow->nw_dst = get_16aligned_be32(&nh->ip_dst);
return;
}
- packet->l4 = b.data;
+ ofpbuf_set_l4(packet, b.data);
if (flow->nw_proto == IPPROTO_TCP) {
parse_tcp(&b, flow);
} else if (flow->nw_proto == IPPROTO_UDP) {
flow->mpls_lse[idx] = lse;
}
-static uint8_t *
+static size_t
flow_compose_l4(struct ofpbuf *b, const struct flow *flow)
{
+ size_t l4_len = 0;
+
if (!(flow->nw_frag & FLOW_NW_FRAG_ANY)
|| !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
if (flow->nw_proto == IPPROTO_TCP) {
struct tcp_header *tcp;
- tcp = ofpbuf_put_zeros(b, sizeof *tcp);
+ l4_len = sizeof *tcp;
+ tcp = ofpbuf_put_zeros(b, l4_len);
tcp->tcp_src = flow->tp_src;
tcp->tcp_dst = flow->tp_dst;
tcp->tcp_ctl = TCP_CTL(ntohs(flow->tcp_flags), 5);
- return ofpbuf_tail(b);
} else if (flow->nw_proto == IPPROTO_UDP) {
struct udp_header *udp;
- udp = ofpbuf_put_zeros(b, sizeof *udp);
+ l4_len = sizeof *udp;
+ udp = ofpbuf_put_zeros(b, l4_len);
udp->udp_src = flow->tp_src;
udp->udp_dst = flow->tp_dst;
- return ofpbuf_tail(b);
} else if (flow->nw_proto == IPPROTO_SCTP) {
struct sctp_header *sctp;
- sctp = ofpbuf_put_zeros(b, sizeof *sctp);
+ l4_len = sizeof *sctp;
+ sctp = ofpbuf_put_zeros(b, l4_len);
sctp->sctp_src = flow->tp_src;
sctp->sctp_dst = flow->tp_dst;
- return ofpbuf_tail(b);
} else if (flow->nw_proto == IPPROTO_ICMP) {
struct icmp_header *icmp;
- icmp = ofpbuf_put_zeros(b, sizeof *icmp);
+ l4_len = sizeof *icmp;
+ icmp = ofpbuf_put_zeros(b, l4_len);
icmp->icmp_type = ntohs(flow->tp_src);
icmp->icmp_code = ntohs(flow->tp_dst);
icmp->icmp_csum = csum(icmp, ICMP_HEADER_LEN);
- return ofpbuf_tail(b);
} else if (flow->nw_proto == IPPROTO_ICMPV6) {
struct icmp6_hdr *icmp;
- icmp = ofpbuf_put_zeros(b, sizeof *icmp);
+ l4_len = sizeof *icmp;
+ icmp = ofpbuf_put_zeros(b, l4_len);
icmp->icmp6_type = ntohs(flow->tp_src);
icmp->icmp6_code = ntohs(flow->tp_dst);
struct in6_addr *nd_target;
struct nd_opt_hdr *nd_opt;
+ l4_len += sizeof *nd_target;
nd_target = ofpbuf_put_zeros(b, sizeof *nd_target);
*nd_target = flow->nd_target;
if (!eth_addr_is_zero(flow->arp_sha)) {
+ l4_len += 8;
nd_opt = ofpbuf_put_zeros(b, 8);
nd_opt->nd_opt_len = 1;
nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
memcpy(nd_opt + 1, flow->arp_sha, ETH_ADDR_LEN);
}
if (!eth_addr_is_zero(flow->arp_tha)) {
+ l4_len += 8;
nd_opt = ofpbuf_put_zeros(b, 8);
nd_opt->nd_opt_len = 1;
nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
}
icmp->icmp6_cksum = (OVS_FORCE uint16_t)
csum(icmp, (char *)ofpbuf_tail(b) - (char *)icmp);
- return ofpbuf_tail(b);
}
}
- return NULL;
+ return l4_len;
}
/* Puts into 'b' a packet that flow_extract() would parse as having the given
void
flow_compose(struct ofpbuf *b, const struct flow *flow)
{
+ size_t l4_len;
+
/* eth_compose() sets l3 pointer and makes sure it is 32-bit aligned. */
eth_compose(b, flow->dl_dst, flow->dl_src, ntohs(flow->dl_type), 0);
if (flow->dl_type == htons(FLOW_DL_TYPE_NONE)) {
}
}
- b->l4 = ofpbuf_tail(b);
+ ofpbuf_set_l4(b, ofpbuf_tail(b));
- flow_compose_l4(b, flow);
+ l4_len = flow_compose_l4(b, flow);
- ip->ip_tot_len = htons((uint8_t *) b->data + b->size
- - (uint8_t *) b->l3);
+ ip->ip_tot_len = htons(b->l4_ofs - b->l3_ofs + l4_len);
ip->ip_csum = csum(ip, sizeof *ip);
} else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
struct ovs_16aligned_ip6_hdr *nh;
- uint8_t *l7;
nh = ofpbuf_put_zeros(b, sizeof *nh);
put_16aligned_be32(&nh->ip6_flow, htonl(6 << 28) |
memcpy(&nh->ip6_src, &flow->ipv6_src, sizeof(nh->ip6_src));
memcpy(&nh->ip6_dst, &flow->ipv6_dst, sizeof(nh->ip6_dst));
- b->l4 = ofpbuf_tail(b);
+ ofpbuf_set_l4(b, ofpbuf_tail(b));
- l7 = flow_compose_l4(b, flow);
+ l4_len = flow_compose_l4(b, flow);
- nh->ip6_plen = l7 ? htons(l7 - (uint8_t *) b->l4) : htons(0);
+ nh->ip6_plen = htons(l4_len);
} else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
flow->dl_type == htons(ETH_TYPE_RARP)) {
struct arp_eth_header *arp;
- b->l3 = arp = ofpbuf_put_zeros(b, sizeof *arp);
+ arp = ofpbuf_put_zeros(b, sizeof *arp);
+ ofpbuf_set_l3(b, arp);
arp->ar_hrd = htons(1);
arp->ar_pro = htons(ETH_TYPE_IP);
arp->ar_hln = ETH_ADDR_LEN;
if (eth_type_mpls(flow->dl_type)) {
int n;
- b->l2_5 = b->l3;
+ b->l2_5_ofs = b->l3_ofs;
for (n = 1; n < FLOW_MAX_MPLS_LABELS; n++) {
if (flow->mpls_lse[n - 1] & htonl(MPLS_BOS_MASK)) {
break;
{
const struct lacp_pdu *pdu;
- pdu = ofpbuf_at(b, (uint8_t *)b->l3 - (uint8_t *)b->data, LACP_PDU_LEN);
+ pdu = ofpbuf_at(b, (uint8_t *)ofpbuf_get_l3(b) - (uint8_t *)b->data,
+ LACP_PDU_LEN);
if (pdu && pdu->subtype == 1
&& pdu->actor_type == 1 && pdu->actor_len == 20
struct nlmsgerr *err = ofpbuf_at(msg, NLMSG_HDRLEN, sizeof *err);
int code = EPROTO;
if (!err) {
- VLOG_ERR_RL(&rl, "received invalid nlmsgerr (%"PRIuSIZE"d bytes < %"PRIuSIZE"d)",
+ VLOG_ERR_RL(&rl, "received invalid nlmsgerr (%"PRIu32"d bytes < %"PRIuSIZE"d)",
msg->size, NLMSG_HDRLEN + sizeof *err);
} else if (err->error <= 0 && err->error > INT_MIN) {
code = -err->error;
if (!p) {
VLOG_DBG_RL(&rl, "nx_match length %u, rounded up to a "
"multiple of 8, is longer than space in message (max "
- "length %"PRIuSIZE")", match_len, b->size);
+ "length %"PRIu32")", match_len, b->size);
return OFPERR_OFPBMC_BAD_LEN;
}
}
if (!p) {
VLOG_DBG_RL(&rl, "oxm length %u, rounded up to a "
"multiple of 8, is longer than space in message (max "
- "length %"PRIuSIZE")", match_len, b->size);
+ "length %"PRIu32")", match_len, b->size);
return OFPERR_OFPBMC_BAD_LEN;
}
static void
set_arp(struct ofpbuf *packet, const struct ovs_key_arp *arp_key)
{
- struct arp_eth_header *arp = packet->l3;
+ struct arp_eth_header *arp = ofpbuf_get_l3(packet);
arp->ar_op = arp_key->arp_op;
memcpy(arp->ar_sha, arp_key->arp_sha, ETH_ADDR_LEN);
actions = ofpbuf_try_pull(openflow, actions_len);
if (actions == NULL) {
VLOG_WARN_RL(&rl, "OpenFlow message actions length %u exceeds "
- "remaining message length (%"PRIuSIZE")",
+ "remaining message length (%"PRIu32")",
actions_len, openflow->size);
return OFPERR_OFPBRC_BAD_LEN;
}
instructions = ofpbuf_try_pull(openflow, instructions_len);
if (instructions == NULL) {
VLOG_WARN_RL(&rl, "OpenFlow message instructions length %u exceeds "
- "remaining message length (%"PRIuSIZE")",
+ "remaining message length (%"PRIu32")",
instructions_len, openflow->size);
error = OFPERR_OFPBIC_BAD_LEN;
goto exit;
enum ofpraw raw;
/* Set default outputs. */
- msg->l2 = msg->l3 = msg->data;
+ msg->l2 = msg->data;
+ ofpbuf_set_l3(msg, msg->data);
*rawp = 0;
len = msg->size;
info = raw_info_get(raw);
instance = raw_instance_get(info, hdrs.version);
msg->l2 = ofpbuf_pull(msg, instance->hdrs_len);
- msg->l3 = msg->data;
+ ofpbuf_set_l3(msg, msg->data);
min_len = instance->hdrs_len + info->min_body;
switch (info->extra_multiple) {
ofpbuf_prealloc_tailroom(buf, (instance->hdrs_len + info->min_body
+ extra_tailroom));
buf->l2 = ofpbuf_put_uninit(buf, instance->hdrs_len);
- buf->l3 = ofpbuf_tail(buf);
+ ofpbuf_set_l3(buf, ofpbuf_tail(buf));
oh = buf->l2;
oh->version = version;
next = ofpbuf_new(MAX(1024, hdrs_len + len));
ofpbuf_put(next, msg->data, hdrs_len);
next->l2 = next->data;
- next->l3 = ofpbuf_tail(next);
+ ofpbuf_set_l3(next, ofpbuf_tail(next));
list_push_back(replies, &next->list_node);
*ofpmp_flags__(msg->data) |= htons(OFPSF_REPLY_MORE);
l4_size = ofpbuf_get_l4_size(&buf);
if (flow.nw_proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {
- struct tcp_header *th = buf.l4;
+ struct tcp_header *th = ofpbuf_get_l4(&buf);
ds_put_format(&ds, " tcp_csum:%"PRIx16, ntohs(th->tcp_csum));
} else if (flow.nw_proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN) {
- struct udp_header *uh = buf.l4;
+ struct udp_header *uh = ofpbuf_get_l4(&buf);
ds_put_format(&ds, " udp_csum:%"PRIx16, ntohs(uh->udp_csum));
} else if (flow.nw_proto == IPPROTO_SCTP && l4_size >= SCTP_HEADER_LEN) {
- struct sctp_header *sh = buf.l4;
+ struct sctp_header *sh = ofpbuf_get_l4(&buf);
ds_put_format(&ds, " sctp_csum:%"PRIx32, ntohl(sh->sctp_csum));
}
omc = ofpbuf_try_pull(msg, sizeof *omc);
if (!omc) {
VLOG_WARN_RL(&bad_ofmsg_rl,
- "OFPMP_METER_CONFIG reply has %"PRIuSIZE" leftover bytes at end",
+ "OFPMP_METER_CONFIG reply has %"PRIu32" leftover bytes at end",
msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
oms = ofpbuf_try_pull(msg, sizeof *oms);
if (!oms) {
VLOG_WARN_RL(&bad_ofmsg_rl,
- "OFPMP_METER reply has %"PRIuSIZE" leftover bytes at end",
+ "OFPMP_METER reply has %"PRIu32" leftover bytes at end",
msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
nfm->command = ofputil_tid_command(fm, protocol);
nfm->cookie = fm->new_cookie;
match_len = nx_put_match(msg, &fm->match, fm->cookie, fm->cookie_mask);
- nfm = msg->l3;
+ nfm = ofpbuf_get_l3(msg);
nfm->idle_timeout = htons(fm->idle_timeout);
nfm->hard_timeout = htons(fm->hard_timeout);
nfm->priority = htons(fm->priority);
struct ofp12_packet_queue *opq12;
ovs_be32 port;
- qgcr11 = reply->l3;
+ qgcr11 = ofpbuf_get_l3(reply);
port = qgcr11->port;
opq12 = ofpbuf_put_zeros(reply, sizeof *opq12);
match_len = nx_put_match(msg, &fsr->match,
fsr->cookie, fsr->cookie_mask);
- nfsr = msg->l3;
+ nfsr = ofpbuf_get_l3(msg);
nfsr->out_port = htons(ofp_to_u16(fsr->out_port));
nfsr->match_len = htons(match_len);
nfsr->table_id = fsr->table_id;
ofs = ofpbuf_try_pull(msg, sizeof *ofs);
if (!ofs) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %"PRIuSIZE" leftover "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %"PRIu32" leftover "
"bytes at end", msg->size);
return EINVAL;
}
ofs = ofpbuf_try_pull(msg, sizeof *ofs);
if (!ofs) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %"PRIuSIZE" leftover "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_FLOW reply has %"PRIu32" leftover "
"bytes at end", msg->size);
return EINVAL;
}
nfs = ofpbuf_try_pull(msg, sizeof *nfs);
if (!nfs) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW reply has %"PRIuSIZE" leftover "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW reply has %"PRIu32" leftover "
"bytes at end", msg->size);
return EINVAL;
}
ofpbuf_use_const(&msg, reply, ntohs(reply->length));
ofpraw_pull_assert(&msg);
- asr = msg.l3;
+ asr = ofpbuf_get_l3(&msg);
stats->packet_count = ntohll(get_32aligned_be64(&asr->packet_count));
stats->byte_count = ntohll(get_32aligned_be64(&asr->byte_count));
stats->flow_count = ntohl(asr->flow_count);
nfr = ofpbuf_put_zeros(msg, sizeof *nfr);
match_len = nx_put_match(msg, &fr->match, 0, 0);
- nfr = msg->l3;
+ nfr = ofpbuf_get_l3(msg);
nfr->cookie = fr->cookie;
nfr->priority = htons(fr->priority);
nfr->reason = fr->reason;
ofpbuf_put_zeros(packet, 2);
ofpbuf_put(packet, pin->packet, pin->packet_len);
- npi = packet->l3;
+ npi = ofpbuf_get_l3(packet);
npi->buffer_id = htonl(pin->buffer_id);
npi->total_len = htons(pin->total_len);
npi->reason = pin->reason;
ofpbuf_put_zeros(packet, 2);
ofpbuf_put(packet, pin->packet, pin->packet_len);
- opi = packet->l3;
+ opi = ofpbuf_get_l3(packet);
opi->pi.buffer_id = htonl(pin->buffer_id);
opi->pi.total_len = htons(pin->total_len);
opi->pi.reason = pin->reason;
if (raw == OFPRAW_OFPT12_ROLE_REQUEST ||
raw == OFPRAW_OFPT12_ROLE_REPLY) {
- const struct ofp12_role_request *orr = b.l3;
+ const struct ofp12_role_request *orr = ofpbuf_get_l3(&b);
if (orr->role != htonl(OFPCR12_ROLE_NOCHANGE) &&
orr->role != htonl(OFPCR12_ROLE_EQUAL) &&
}
} else if (raw == OFPRAW_NXT_ROLE_REQUEST ||
raw == OFPRAW_NXT_ROLE_REPLY) {
- const struct nx_role_request *nrr = b.l3;
+ const struct nx_role_request *nrr = ofpbuf_get_l3(&b);
BUILD_ASSERT(NX_ROLE_OTHER + 1 == OFPCR12_ROLE_EQUAL);
BUILD_ASSERT(NX_ROLE_MASTER + 1 == OFPCR12_ROLE_MASTER);
raw = ofpraw_pull_assert(&b);
ovs_assert(raw == OFPRAW_OFPT14_ROLE_STATUS);
- r = b.l3;
+ r = ofpbuf_get_l3(&b);
if (r->role != htonl(OFPCR12_ROLE_NOCHANGE) &&
r->role != htonl(OFPCR12_ROLE_EQUAL) &&
r->role != htonl(OFPCR12_ROLE_MASTER) &&
nfmr = ofpbuf_try_pull(msg, sizeof *nfmr);
if (!nfmr) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR request has %"PRIuSIZE" "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR request has %"PRIu32" "
"leftover bytes at end", msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
}
bad_len:
- VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR reply has %"PRIuSIZE" "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR reply has %"PRIu32" "
"leftover bytes at end", msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg,
ofp_version);
- opo = msg->l3;
+ opo = ofpbuf_get_l3(msg);
opo->buffer_id = htonl(po->buffer_id);
opo->in_port = htons(ofp_to_u16(po->in_port));
opo->actions_len = htons(msg->size - actions_ofs);
ofpbuf_put_zeros(msg, sizeof *opo);
len = ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg,
ofp_version);
- opo = msg->l3;
+ opo = ofpbuf_get_l3(msg);
opo->buffer_id = htonl(po->buffer_id);
opo->in_port = ofputil_port_to_ofp11(po->in_port);
opo->actions_len = htons(len);
}
bad_len:
- VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_PORT reply has %"PRIuSIZE" leftover "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_PORT reply has %"PRIu32" leftover "
"bytes at end", msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
}
if (!ogs11) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "%s reply has %"PRIuSIZE" leftover bytes at end",
+ VLOG_WARN_RL(&bad_ofmsg_rl, "%s reply has %"PRIu32" leftover bytes at end",
ofpraw_get_name(raw), msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
gs->n_buckets = (length - base_len) / sizeof *obc;
obc = ofpbuf_try_pull(msg, gs->n_buckets * sizeof *obc);
if (!obc) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "%s reply has %"PRIuSIZE" leftover bytes at end",
+ VLOG_WARN_RL(&bad_ofmsg_rl, "%s reply has %"PRIu32" leftover bytes at end",
ofpraw_get_name(raw), msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
ogds = ofpbuf_try_pull(msg, sizeof *ogds);
if (!ogds) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply has %"PRIuSIZE" "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST11_GROUP_DESC reply has %"PRIu32" "
"leftover bytes at end", msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
}
bad_len:
- VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_QUEUE reply has %"PRIuSIZE" leftover "
+ VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_QUEUE reply has %"PRIu32" leftover "
"bytes at end", msg->size);
return OFPERR_OFPBRC_BAD_LEN;
}
b->allocated = allocated;
b->source = source;
b->size = 0;
- b->l2 = b->l2_5 = b->l3 = b->l4 = NULL;
+ b->l2 = NULL;
+ b->l2_5_ofs = b->l3_ofs = b->l4_ofs = UINT16_MAX;
list_poison(&b->list_node);
- b->private_p = NULL;
}
/* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of
ofpbuf_clone_with_headroom(const struct ofpbuf *buffer, size_t headroom)
{
struct ofpbuf *new_buffer;
- uintptr_t data_delta;
new_buffer = ofpbuf_clone_data_with_headroom(buffer->data, buffer->size,
headroom);
- data_delta = (char *) new_buffer->data - (char *) buffer->data;
-
if (buffer->l2) {
+ uintptr_t data_delta = (char *)new_buffer->data - (char *)buffer->data;
+
new_buffer->l2 = (char *) buffer->l2 + data_delta;
}
- if (buffer->l2_5) {
- new_buffer->l2_5 = (char *) buffer->l2_5 + data_delta;
- }
- if (buffer->l3) {
- new_buffer->l3 = (char *) buffer->l3 + data_delta;
- }
- if (buffer->l4) {
- new_buffer->l4 = (char *) buffer->l4 + data_delta;
- }
+ new_buffer->l2_5_ofs = buffer->l2_5_ofs;
+ new_buffer->l3_ofs = buffer->l3_ofs;
+ new_buffer->l4_ofs = buffer->l4_ofs;
return new_buffer;
}
new_data = (char *) new_base + new_headroom;
if (b->data != new_data) {
uintptr_t data_delta = (char *) new_data - (char *) b->data;
+
b->data = new_data;
if (b->l2) {
b->l2 = (char *) b->l2 + data_delta;
}
- if (b->l2_5) {
- b->l2_5 = (char *) b->l2_5 + data_delta;
- }
- if (b->l3) {
- b->l3 = (char *) b->l3 + data_delta;
- }
- if (b->l4) {
- b->l4 = (char *) b->l4 + data_delta;
- }
}
}
struct ds s;
ds_init(&s);
- ds_put_format(&s, "size=%"PRIuSIZE", allocated=%"PRIuSIZE", head=%"PRIuSIZE", tail=%"PRIuSIZE"\n",
+ ds_put_format(&s, "size=%"PRIu32", allocated=%"PRIu32", head=%"PRIuSIZE", tail=%"PRIuSIZE"\n",
b->size, b->allocated,
ofpbuf_headroom(b), ofpbuf_tailroom(b));
ds_put_hex_dump(&s, b->data, MIN(b->size, maxbytes), 0, false);
ofpbuf_delete(b);
}
}
+
+static inline void
+ofpbuf_adjust_layer_offset(uint16_t *offset, int increment)
+{
+ if (*offset != UINT16_MAX) {
+ *offset += increment;
+ }
+}
+
+/* Adjust the size of the l2_5 portion of the ofpbuf, updating the l2
+ * pointer and the layer offsets. The caller is responsible for
+ * modifying the contents. */
+void *
+ofpbuf_resize_l2_5(struct ofpbuf *b, int increment)
+{
+ if (increment >= 0) {
+ ofpbuf_push_uninit(b, increment);
+ } else {
+ ofpbuf_pull(b, -increment);
+ }
+
+ b->l2 = b->data;
+ /* Adjust layer offsets after l2_5. */
+ ofpbuf_adjust_layer_offset(&b->l3_ofs, increment);
+ ofpbuf_adjust_layer_offset(&b->l4_ofs, increment);
+
+ return b->l2;
+}
+
+/* Adjust the size of the l2 portion of the ofpbuf, updating the l2
+ * pointer and the layer offsets. The caller is responsible for
+ * modifying the contents. */
+void *
+ofpbuf_resize_l2(struct ofpbuf *b, int increment)
+{
+ ofpbuf_resize_l2_5(b, increment);
+ ofpbuf_adjust_layer_offset(&b->l2_5_ofs, increment);
+ return b->l2;
+}
extern "C" {
#endif
-enum ofpbuf_source {
+enum OVS_PACKED_ENUM ofpbuf_source {
OFPBUF_MALLOC, /* Obtained via malloc(). */
OFPBUF_STACK, /* Un-movable stack space or static buffer. */
OFPBUF_STUB, /* Starts on stack, may expand into heap. */
* as necessary if it grows too large for the available memory. */
struct ofpbuf {
void *base; /* First byte of allocated space. */
- size_t allocated; /* Number of bytes allocated. */
- enum ofpbuf_source source; /* Source of memory allocated as 'base'. */
-
+ uint32_t allocated; /* Number of bytes allocated. */
+ uint32_t size; /* Number of bytes in use. */
void *data; /* First byte actually in use. */
- size_t size; /* Number of bytes in use. */
void *l2; /* Link-level header. */
- void *l2_5; /* MPLS label stack */
- void *l3; /* Network-level header. */
- void *l4; /* Transport-level header. */
-
+ uint16_t l2_5_ofs; /* MPLS label stack offset from l2, or
+ * UINT16_MAX */
+ uint16_t l3_ofs; /* Network-level header offset from l2, or
+ * UINT16_MAX. */
+ uint16_t l4_ofs; /* Transport-level header offset from l2, or
+ UINT16_MAX. */
+ enum ofpbuf_source source; /* Source of memory allocated as 'base'. */
struct list list_node; /* Private list element for use by owner. */
- void *private_p; /* Private pointer for use by owner. */
};
+void * ofpbuf_resize_l2(struct ofpbuf *, int increment);
+void * ofpbuf_resize_l2_5(struct ofpbuf *, int increment);
+static inline void * ofpbuf_get_l2_5(const struct ofpbuf *);
+static inline void ofpbuf_set_l2_5(struct ofpbuf *, void *);
+static inline void * ofpbuf_get_l3(const struct ofpbuf *);
+static inline void ofpbuf_set_l3(struct ofpbuf *, void *);
+static inline void * ofpbuf_get_l4(const struct ofpbuf *);
+static inline void ofpbuf_set_l4(struct ofpbuf *, void *);
+static inline size_t ofpbuf_get_l4_size(const struct ofpbuf *);
+static inline const void *ofpbuf_get_tcp_payload(const struct ofpbuf *);
+static inline const void *ofpbuf_get_udp_payload(const struct ofpbuf *);
+static inline const void *ofpbuf_get_sctp_payload(const struct ofpbuf *);
+static inline const void *ofpbuf_get_icmp_payload(const struct ofpbuf *);
+
void ofpbuf_use(struct ofpbuf *, void *, size_t);
void ofpbuf_use_stack(struct ofpbuf *, void *, size_t);
void ofpbuf_use_stub(struct ofpbuf *, void *, size_t);
return a->size == b->size && memcmp(a->data, b->data, a->size) == 0;
}
+static inline void * ofpbuf_get_l2_5(const struct ofpbuf *b)
+{
+ return b->l2_5_ofs != UINT16_MAX ? (char *)b->l2 + b->l2_5_ofs : NULL;
+}
+
+static inline void ofpbuf_set_l2_5(struct ofpbuf *b, void *l2_5)
+{
+ b->l2_5_ofs = l2_5 ? (char *)l2_5 - (char *)b->l2 : UINT16_MAX;
+}
+
+static inline void * ofpbuf_get_l3(const struct ofpbuf *b)
+{
+ return b->l3_ofs != UINT16_MAX ? (char *)b->l2 + b->l3_ofs : NULL;
+}
+
+static inline void ofpbuf_set_l3(struct ofpbuf *b, void *l3)
+{
+ b->l3_ofs = l3 ? (char *)l3 - (char *)b->l2 : UINT16_MAX;
+}
+
+static inline void * ofpbuf_get_l4(const struct ofpbuf *b)
+{
+ return b->l4_ofs != UINT16_MAX ? (char *)b->l2 + b->l4_ofs : NULL;
+}
+
+static inline void ofpbuf_set_l4(struct ofpbuf *b, void *l4)
+{
+ b->l4_ofs = l4 ? (char *)l4 - (char *)b->l2 : UINT16_MAX;
+}
+
static inline size_t ofpbuf_get_l4_size(const struct ofpbuf *b)
{
- return b->l4 ? (const char *)ofpbuf_tail(b) - (const char *)b->l4 : 0;
+ return b->l4_ofs != UINT16_MAX
+ ? (const char *)ofpbuf_tail(b) - (const char *)ofpbuf_get_l4(b) : 0;
}
static inline const void *ofpbuf_get_tcp_payload(const struct ofpbuf *b)
size_t l4_size = ofpbuf_get_l4_size(b);
if (OVS_LIKELY(l4_size >= TCP_HEADER_LEN)) {
- struct tcp_header *tcp = b->l4;
+ struct tcp_header *tcp = ofpbuf_get_l4(b);
int tcp_len = TCP_OFFSET(tcp->tcp_ctl) * 4;
if (OVS_LIKELY(tcp_len >= TCP_HEADER_LEN && tcp_len <= l4_size)) {
static inline const void *ofpbuf_get_udp_payload(const struct ofpbuf *b)
{
return OVS_LIKELY(ofpbuf_get_l4_size(b) >= UDP_HEADER_LEN)
- ? (const char *)b->l4 + UDP_HEADER_LEN : NULL;
+ ? (const char *)ofpbuf_get_l4(b) + UDP_HEADER_LEN : NULL;
}
static inline const void *ofpbuf_get_sctp_payload(const struct ofpbuf *b)
{
return OVS_LIKELY(ofpbuf_get_l4_size(b) >= SCTP_HEADER_LEN)
- ? (const char *)b->l4 + SCTP_HEADER_LEN : NULL;
+ ? (const char *)ofpbuf_get_l4(b) + SCTP_HEADER_LEN : NULL;
}
static inline const void *ofpbuf_get_icmp_payload(const struct ofpbuf *b)
{
return OVS_LIKELY(ofpbuf_get_l4_size(b) >= ICMP_HEADER_LEN)
- ? (const char *)b->l4 + ICMP_HEADER_LEN : NULL;
+ ? (const char *)ofpbuf_get_l4(b) + ICMP_HEADER_LEN : NULL;
}
#ifdef __cplusplus
/* Insert VLAN header according to given TCI. Packet passed must be Ethernet
* packet. Ignores the CFI bit of 'tci' using 0 instead.
*
- * Also sets 'packet->l2' to point to the new Ethernet header. */
+ * Also sets 'packet->l2' to point to the new Ethernet header and adjusts
+ * the layer offsets accordingly. */
void
eth_push_vlan(struct ofpbuf *packet, ovs_be16 tpid, ovs_be16 tci)
{
- struct eth_header *eh = packet->data;
struct vlan_eth_header *veh;
/* Insert new 802.1Q header. */
- struct vlan_eth_header tmp;
- memcpy(tmp.veth_dst, eh->eth_dst, ETH_ADDR_LEN);
- memcpy(tmp.veth_src, eh->eth_src, ETH_ADDR_LEN);
- tmp.veth_type = tpid;
- tmp.veth_tci = tci & htons(~VLAN_CFI);
- tmp.veth_next_type = eh->eth_type;
-
- veh = ofpbuf_push_uninit(packet, VLAN_HEADER_LEN);
- memcpy(veh, &tmp, sizeof tmp);
-
- packet->l2 = packet->data;
+ veh = ofpbuf_resize_l2(packet, VLAN_HEADER_LEN);
+ memmove(veh, (char *)veh + VLAN_HEADER_LEN, 2 * ETH_ADDR_LEN);
+ veh->veth_type = tpid;
+ veh->veth_tci = tci & htons(~VLAN_CFI);
}
/* Removes outermost VLAN header (if any is present) from 'packet'.
eth_pop_vlan(struct ofpbuf *packet)
{
struct vlan_eth_header *veh = packet->l2;
+
if (packet->size >= sizeof *veh
&& veh->veth_type == htons(ETH_TYPE_VLAN)) {
- struct eth_header tmp;
- memcpy(tmp.eth_dst, veh->veth_dst, ETH_ADDR_LEN);
- memcpy(tmp.eth_src, veh->veth_src, ETH_ADDR_LEN);
- tmp.eth_type = veh->veth_next_type;
-
- ofpbuf_pull(packet, VLAN_HEADER_LEN);
- packet->l2 = (char*)packet->l2 + VLAN_HEADER_LEN;
- memcpy(packet->data, &tmp, sizeof tmp);
+ memmove((char *)veh + VLAN_HEADER_LEN, veh, 2 * ETH_ADDR_LEN);
+ ofpbuf_resize_l2(packet, -VLAN_HEADER_LEN);
}
}
static void
set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type)
{
- struct eth_header *eh = packet->data;
+ struct eth_header *eh = packet->l2;
if (eh->eth_type == htons(ETH_TYPE_VLAN)) {
ovs_be16 *p;
+ char *l2_5 = ofpbuf_get_l2_5(packet);
+
p = ALIGNED_CAST(ovs_be16 *,
- (char *)(packet->l2_5 ? packet->l2_5 : packet->l3) - 2);
+ (l2_5 ? l2_5 : (char *)ofpbuf_get_l3(packet)) - 2);
*p = eth_type;
} else {
eh->eth_type = eth_type;
static bool is_mpls(struct ofpbuf *packet)
{
- return packet->l2_5 != NULL;
+ return packet->l2_5_ofs != UINT16_MAX;
}
/* Set time to live (TTL) of an MPLS label stack entry (LSE). */
return lse;
}
-/* Push an new MPLS stack entry onto the MPLS stack and adjust 'packet->l2' and
- * 'packet->l2_5' accordingly. The new entry will be the outermost entry on
- * the stack.
- *
- * Previous to calling this function, 'packet->l2_5' must be set; if the MPLS
- * label to be pushed will be the first label in 'packet', then it should be
- * the same as 'packet->l3'. */
-static void
-push_mpls_lse(struct ofpbuf *packet, struct mpls_hdr *mh)
-{
- char * header;
- size_t len;
- header = ofpbuf_push_uninit(packet, MPLS_HLEN);
- len = (char *)packet->l2_5 - (char *)packet->l2;
- memmove(header, packet->l2, len);
- memcpy(header + len, mh, sizeof *mh);
- packet->l2 = (char*)packet->l2 - MPLS_HLEN;
- packet->l2_5 = (char*)packet->l2_5 - MPLS_HLEN;
-}
-
/* Set MPLS label stack entry to outermost MPLS header.*/
void
set_mpls_lse(struct ofpbuf *packet, ovs_be32 mpls_lse)
{
- struct mpls_hdr *mh = packet->l2_5;
-
/* Packet type should be MPLS to set label stack entry. */
if (is_mpls(packet)) {
+ struct mpls_hdr *mh = ofpbuf_get_l2_5(packet);
+
/* Update mpls label stack entry. */
mh->mpls_lse = mpls_lse;
}
void
push_mpls(struct ofpbuf *packet, ovs_be16 ethtype, ovs_be32 lse)
{
- struct mpls_hdr mh;
+ char * header;
+ size_t len;
if (!eth_type_mpls(ethtype)) {
return;
}
- set_ethertype(packet, ethtype);
-
if (!is_mpls(packet)) {
- /* Set MPLS label stack entry. */
- packet->l2_5 = packet->l3;
+ /* Set MPLS label stack offset. */
+ packet->l2_5_ofs = packet->l3_ofs;
}
+ set_ethertype(packet, ethtype);
+
/* Push new MPLS shim header onto packet. */
- mh.mpls_lse = lse;
- push_mpls_lse(packet, &mh);
+ len = packet->l2_5_ofs;
+ header = ofpbuf_resize_l2_5(packet, MPLS_HLEN);
+ memmove(header, header + MPLS_HLEN, len);
+ memcpy(header + len, &lse, sizeof lse);
}
/* If 'packet' is an MPLS packet, removes its outermost MPLS label stack entry.
void
pop_mpls(struct ofpbuf *packet, ovs_be16 ethtype)
{
- struct mpls_hdr *mh = NULL;
-
if (is_mpls(packet)) {
- size_t len;
- mh = packet->l2_5;
- len = (char*)packet->l2_5 - (char*)packet->l2;
+ struct mpls_hdr *mh = ofpbuf_get_l2_5(packet);
+ size_t len = packet->l2_5_ofs;
+
set_ethertype(packet, ethtype);
if (mh->mpls_lse & htonl(MPLS_BOS_MASK)) {
- packet->l2_5 = NULL;
- } else {
- packet->l2_5 = (char*)packet->l2_5 + MPLS_HLEN;
+ ofpbuf_set_l2_5(packet, NULL);
}
/* Shift the l2 header forward. */
memmove((char*)packet->data + MPLS_HLEN, packet->data, len);
- packet->size -= MPLS_HLEN;
- packet->data = (char*)packet->data + MPLS_HLEN;
- packet->l2 = (char*)packet->l2 + MPLS_HLEN;
+ ofpbuf_resize_l2_5(packet, -MPLS_HLEN);
}
}
/* Populates 'b' with an Ethernet II packet headed with the given 'eth_dst',
* 'eth_src' and 'eth_type' parameters. A payload of 'size' bytes is allocated
* in 'b' and returned. This payload may be populated with appropriate
- * information by the caller. Sets 'b''s 'l2' and 'l3' pointers to the
+ * information by the caller. Sets 'b''s 'l2' pointer and 'l3' offset to the
* Ethernet header and payload respectively. Aligns b->l3 on a 32-bit
* boundary.
*
eth->eth_type = htons(eth_type);
b->l2 = eth;
- b->l3 = data;
+ ofpbuf_set_l3(b, data);
return data;
}
packet_set_ipv4_addr(struct ofpbuf *packet,
ovs_16aligned_be32 *addr, ovs_be32 new_addr)
{
- struct ip_header *nh = packet->l3;
+ struct ip_header *nh = ofpbuf_get_l3(packet);
ovs_be32 old_addr = get_16aligned_be32(addr);
size_t l4_size = ofpbuf_get_l4_size(packet);
if (nh->ip_proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {
- struct tcp_header *th = packet->l4;
+ struct tcp_header *th = ofpbuf_get_l4(packet);
th->tcp_csum = recalc_csum32(th->tcp_csum, old_addr, new_addr);
} else if (nh->ip_proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN ) {
- struct udp_header *uh = packet->l4;
+ struct udp_header *uh = ofpbuf_get_l4(packet);
if (uh->udp_csum) {
uh->udp_csum = recalc_csum32(uh->udp_csum, old_addr, new_addr);
/* Returns true, if packet contains at least one routing header where
* segements_left > 0.
*
- * This function assumes that L3 and L4 markers are set in the packet. */
+ * This function assumes that L3 and L4 offsets are set in the packet. */
static bool
packet_rh_present(struct ofpbuf *packet)
{
int nexthdr;
size_t len;
size_t remaining;
- uint8_t *data = packet->l3;
+ uint8_t *data = ofpbuf_get_l3(packet);
- remaining = (uint8_t *)packet->l4 - (uint8_t *)packet->l3;
+ remaining = packet->l4_ofs - packet->l3_ofs;
if (remaining < sizeof *nh) {
return false;
size_t l4_size = ofpbuf_get_l4_size(packet);
if (proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {
- struct tcp_header *th = packet->l4;
+ struct tcp_header *th = ofpbuf_get_l4(packet);
th->tcp_csum = recalc_csum128(th->tcp_csum, addr, new_addr);
} else if (proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN) {
- struct udp_header *uh = packet->l4;
+ struct udp_header *uh = ofpbuf_get_l4(packet);
if (uh->udp_csum) {
uh->udp_csum = recalc_csum128(uh->udp_csum, addr, new_addr);
packet_set_ipv4(struct ofpbuf *packet, ovs_be32 src, ovs_be32 dst,
uint8_t tos, uint8_t ttl)
{
- struct ip_header *nh = packet->l3;
+ struct ip_header *nh = ofpbuf_get_l3(packet);
if (get_16aligned_be32(&nh->ip_src) != src) {
packet_set_ipv4_addr(packet, &nh->ip_src, src);
/* Modifies the IPv6 header fields of 'packet' to be consistent with 'src',
* 'dst', 'traffic class', and 'next hop'. Updates 'packet''s L4 checksums as
* appropriate. 'packet' must contain a valid IPv6 packet with correctly
- * populated l[347] markers. */
+ * populated l[34] offsets. */
void
packet_set_ipv6(struct ofpbuf *packet, uint8_t proto, const ovs_be32 src[4],
const ovs_be32 dst[4], uint8_t key_tc, ovs_be32 key_fl,
uint8_t key_hl)
{
- struct ovs_16aligned_ip6_hdr *nh = packet->l3;
+ struct ovs_16aligned_ip6_hdr *nh = ofpbuf_get_l3(packet);
if (memcmp(&nh->ip6_src, src, sizeof(ovs_be32[4]))) {
packet_set_ipv6_addr(packet, proto, nh->ip6_src.be32, src, true);
/* Sets the TCP source and destination port ('src' and 'dst' respectively) of
* the TCP header contained in 'packet'. 'packet' must be a valid TCP packet
- * with its l4 marker properly populated. */
+ * with its l4 offset properly populated. */
void
packet_set_tcp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
{
- struct tcp_header *th = packet->l4;
+ struct tcp_header *th = ofpbuf_get_l4(packet);
packet_set_port(&th->tcp_src, src, &th->tcp_csum);
packet_set_port(&th->tcp_dst, dst, &th->tcp_csum);
/* Sets the UDP source and destination port ('src' and 'dst' respectively) of
* the UDP header contained in 'packet'. 'packet' must be a valid UDP packet
- * with its l4 marker properly populated. */
+ * with its l4 offset properly populated. */
void
packet_set_udp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
{
- struct udp_header *uh = packet->l4;
+ struct udp_header *uh = ofpbuf_get_l4(packet);
if (uh->udp_csum) {
packet_set_port(&uh->udp_src, src, &uh->udp_csum);
/* Sets the SCTP source and destination port ('src' and 'dst' respectively) of
* the SCTP header contained in 'packet'. 'packet' must be a valid SCTP packet
- * with its l4 marker properly populated. */
+ * with its l4 offset properly populated. */
void
packet_set_sctp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
{
- struct sctp_header *sh = packet->l4;
+ struct sctp_header *sh = ofpbuf_get_l4(packet);
ovs_be32 old_csum, old_correct_csum, new_csum;
uint16_t tp_len = packet->size - ((uint8_t*)sh - (uint8_t*)packet->data);
old_csum = sh->sctp_csum;
sh->sctp_csum = 0;
- old_correct_csum = crc32c(packet->l4, tp_len);
+ old_correct_csum = crc32c((void *)sh, tp_len);
sh->sctp_src = src;
sh->sctp_dst = dst;
- new_csum = crc32c(packet->l4, tp_len);
+ new_csum = crc32c((void *)sh, tp_len);
sh->sctp_csum = old_csum ^ old_correct_csum ^ new_csum;
}
|| !l7) {
return NULL;
}
- tcp = packet->l4;
+ tcp = ofpbuf_get_l4(packet);
flags = TCP_FLAGS(tcp->tcp_ctl);
l7_length = (char *) ofpbuf_tail(packet) - l7;
seq = ntohl(get_16aligned_be32(&tcp->tcp_seq));
if (rconn_is_connected(rc)) {
COVERAGE_INC(rconn_queued);
copy_to_monitor(rc, b);
- b->private_p = counter;
+
if (counter) {
rconn_packet_counter_inc(counter, b->size);
}
+
+ /* Use 'l2' as a private pointer while 'b' is in txq. */
+ ovs_assert(b->l2 == b->data);
+ b->l2 = counter;
+
list_push_back(&rc->txq, &b->list_node);
/* If the queue was empty before we added 'b', try to send some
{
struct ofpbuf *msg = ofpbuf_from_list(rc->txq.next);
unsigned int n_bytes = msg->size;
- struct rconn_packet_counter *counter = msg->private_p;
+ struct rconn_packet_counter *counter = msg->l2;
int retval;
/* Eagerly remove 'msg' from the txq. We can't remove it from the list
* after sending, if sending is successful, because it is then owned by the
* vconn, which might have freed it already. */
list_remove(&msg->list_node);
+ msg->l2 = msg->data; /* Restore 'l2'. */
retval = vconn_send(rc->vconn, msg);
if (retval) {
+ msg->l2 = counter; /* 'l2' is a private pointer while msg is in txq. */
list_push_front(&rc->txq, &msg->list_node);
if (retval != EAGAIN) {
report_error(rc, retval);
}
while (!list_is_empty(&rc->txq)) {
struct ofpbuf *b = ofpbuf_from_list(list_pop_front(&rc->txq));
- struct rconn_packet_counter *counter = b->private_p;
+ struct rconn_packet_counter *counter = b->l2;
if (counter) {
rconn_packet_counter_dec(counter, b->size);
}
pkt = ofpbuf_new(ETH_HEADER_LEN + LLC_HEADER_LEN + bpdu_size);
pkt->l2 = eth = ofpbuf_put_zeros(pkt, sizeof *eth);
llc = ofpbuf_put_zeros(pkt, sizeof *llc);
- pkt->l3 = ofpbuf_put(pkt, bpdu, bpdu_size);
+ ofpbuf_set_l3(pkt, ofpbuf_put(pkt, bpdu, bpdu_size));
/* 802.2 header. */
memcpy(eth->eth_dst, eth_addr_stp, ETH_ADDR_LEN);
#ifndef UTIL_H
#define UTIL_H 1
+#include <inttypes.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
learning_packet = bond_compose_learning_packet(bundle->bond,
e->mac, e->vlan,
&port_void);
- learning_packet->private_p = port_void;
+ /* Temporarily use l2 as a private pointer (see below). */
+ ovs_assert(learning_packet->l2 == learning_packet->data);
+ learning_packet->l2 = port_void;
list_push_back(&packets, &learning_packet->list_node);
}
}
error = n_packets = n_errors = 0;
LIST_FOR_EACH (learning_packet, list_node, &packets) {
int ret;
+ void *port_void = learning_packet->l2;
- ret = ofproto_dpif_send_packet(learning_packet->private_p, learning_packet);
+ /* Restore l2. */
+ learning_packet->l2 = learning_packet->data;
+ ret = ofproto_dpif_send_packet(port_void, learning_packet);
if (ret) {
error = ret;
n_errors++;
* information in 'flow' is extracted from 'packet', except for
* flow->tunnel and flow->in_port, which are assigned the correct values
* for the incoming packet. The register values are zeroed. 'packet''s
- * header pointers (e.g. packet->l3) are appropriately initialized.
- * packet->l3 is aligned on a 32-bit boundary.
+ * header pointers and offsets (e.g. packet->l3) are appropriately
+ * initialized. packet->l3 is aligned on a 32-bit boundary.
*
* The implementation should add the statistics for 'packet' into 'rule'.
*
}
if (buf->size) {
- printf("%"PRIuSIZE" extra bytes after last record\n", buf->size);
+ printf("%"PRIu32" extra bytes after last record\n", buf->size);
}
}
odp_flow_key_from_flow(&odp_key, &flow, flow.in_port.odp_port);
if (odp_key.size > ODPUTIL_FLOW_KEY_BYTES) {
- printf ("too long: %"PRIuSIZE" > %d\n",
+ printf ("too long: %"PRIu32" > %d\n",
odp_key.size, ODPUTIL_FLOW_KEY_BYTES);
exit_code = 1;
}
assert(port_no < b->n_ports);
lan = b->ports[port_no];
if (lan) {
- const void *data = pkt->l3;
+ const void *data = ofpbuf_get_l3(pkt);
size_t size = (char *) ofpbuf_tail(pkt) - (char *) data;
int i;
if (ofptype_pull(&type, reply)
|| type != OFPTYPE_ECHO_REPLY
|| reply->size != payload
- || memcmp(request->l3, reply->l3, payload)) {
+ || memcmp(ofpbuf_get_l3(request), ofpbuf_get_l3(reply), payload)) {
printf("Reply does not match request. Request:\n");
ofp_print(stdout, request, request->size, verbosity + 2);
printf("Reply:\n");
ofp_print(stdout, reply, reply->size, verbosity + 2);
}
- printf("%"PRIuSIZE" bytes from %s: xid=%08"PRIx32" time=%.1f ms\n",
+ printf("%"PRIu32" bytes from %s: xid=%08"PRIx32" time=%.1f ms\n",
reply->size, argv[1], ntohl(rpy_hdr->xid),
(1000*(double)(end.tv_sec - start.tv_sec))
+ (.001*(end.tv_usec - start.tv_usec)));
ovs_fatal(0, "Trailing garbage in hex data");
}
if (match_expout.size != sizeof(struct ofp10_match)) {
- ovs_fatal(0, "Input is %"PRIuSIZE" bytes, expected %"PRIuSIZE,
+ ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
match_expout.size, sizeof(struct ofp10_match));
}
ovs_fatal(0, "Trailing garbage in hex data");
}
if (match_in.size != sizeof(struct ofp10_match)) {
- ovs_fatal(0, "Input is %"PRIuSIZE" bytes, expected %"PRIuSIZE,
+ ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
match_in.size, sizeof(struct ofp10_match));
}
ovs_fatal(0, "Trailing garbage in hex data");
}
if (match_in.size != sizeof(struct ofp11_match)) {
- ovs_fatal(0, "Input is %"PRIuSIZE" bytes, expected %"PRIuSIZE,
+ ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
match_in.size, sizeof(struct ofp11_match));
}