- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000000ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000001ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000002ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000003ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000004ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000005ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000006ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000007ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000008ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c2000009ULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000aULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000bULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000cULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000dULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000eULL },
- { HMAP_NODE_NULL_INITIALIZER, 0x0108c200000fULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000000ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000001ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000002ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000003ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000004ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000005ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000006ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000007ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000008ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000009ULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000aULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000bULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000cULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000dULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000eULL },
+ { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000fULL },
eth = ofpbuf_put_uninit(b, sizeof *eth);
memcpy(eth->eth_dst, eth_addr_broadcast, ETH_ADDR_LEN);
memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN);
eth = ofpbuf_put_uninit(b, sizeof *eth);
memcpy(eth->eth_dst, eth_addr_broadcast, ETH_ADDR_LEN);
memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN);
- 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 = htons(ETH_TYPE_VLAN);
- 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);
-/* 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;
-}
-
- size_t len;
- mh = packet->l2_5;
- len = (char*)packet->l2_5 - (char*)packet->l2;
- /* If bottom of the stack set ethertype. */
- if (mh->mpls_lse & htonl(MPLS_BOS_MASK)) {
- set_ethertype(packet, ethtype);
- packet->l2_5 = NULL;
- } else {
- packet->l2_5 = (char*)packet->l2_5 + MPLS_HLEN;
+ struct mpls_hdr *mh = ofpbuf_l2_5(packet);
+ size_t len = packet->l2_5_ofs;
+
+ set_ethertype(packet, ethtype);
+ if (get_16aligned_be32(&mh->mpls_lse) & htonl(MPLS_BOS_MASK)) {
+ ofpbuf_set_l2_5(packet, NULL);
/* 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
/* 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
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)
{
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)
{
-/* If 'packet' is a TCP packet, returns the TCP flags. Otherwise, returns 0.
- *
- * 'flow' must be the flow corresponding to 'packet' and 'packet''s header
- * pointers must be properly initialized (e.g. with flow_extract()). */
-uint8_t
-packet_get_tcp_flags(const struct ofpbuf *packet, const struct flow *flow)
-{
- ovs_be16 dl_type = flow_innermost_dl_type(flow);
- if (dl_type_is_ip_any(dl_type) &&
- flow->nw_proto == IPPROTO_TCP && packet->l7) {
- const struct tcp_header *tcp = packet->l4;
- return TCP_FLAGS(tcp->tcp_ctl);
- } else {
- return 0;
+/* 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 offset properly populated. */
+void
+packet_set_sctp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
+{
+ struct sctp_header *sh = ofpbuf_l4(packet);
+ ovs_be32 old_csum, old_correct_csum, new_csum;
+ uint16_t tp_len = ofpbuf_l4_size(packet);
+
+ old_csum = get_16aligned_be32(&sh->sctp_csum);
+ put_16aligned_be32(&sh->sctp_csum, 0);
+ old_correct_csum = crc32c((void *)sh, tp_len);
+
+ sh->sctp_src = src;
+ sh->sctp_dst = dst;
+
+ new_csum = crc32c((void *)sh, tp_len);
+ put_16aligned_be32(&sh->sctp_csum, old_csum ^ old_correct_csum ^ new_csum);
+}
+
+const char *
+packet_tcp_flag_to_string(uint32_t flag)
+{
+ switch (flag) {
+ case TCP_FIN:
+ return "fin";
+ case TCP_SYN:
+ return "syn";
+ case TCP_RST:
+ return "rst";
+ case TCP_PSH:
+ return "psh";
+ case TCP_ACK:
+ return "ack";
+ case TCP_URG:
+ return "urg";
+ case TCP_ECE:
+ return "ece";
+ case TCP_CWR:
+ return "cwr";
+ case TCP_NS:
+ return "ns";
+ case 0x200:
+ return "[200]";
+ case 0x400:
+ return "[400]";
+ case 0x800:
+ return "[800]";
+ default:
+ return NULL;
- if (tcp_flags & 0x40) {
- ds_put_cstr(s, "[40]");
+ if (tcp_flags & TCP_ECE) {
+ ds_put_cstr(s, "E");
+ }
+ if (tcp_flags & TCP_CWR) {
+ ds_put_cstr(s, "C");
+ }
+ if (tcp_flags & TCP_NS) {
+ ds_put_cstr(s, "N");
+ }
+ if (tcp_flags & 0x200) {
+ ds_put_cstr(s, "[200]");
+ }
+ if (tcp_flags & 0x400) {
+ ds_put_cstr(s, "[400]");