On Thu, May 17, 2018 at 02:15:16PM -0700, Greg Rose wrote: > From: William Tu <u9012...@gmail.com> > > ERSPAN is a tunneling protocol based on GRE tunnel. The patch > add erspan tunnel support for ovs-vswitchd with userspace datapath. > Configuring erspan tunnel is similar to gre tunnel, but with > additional erspan's parameters. Matching a flow on erspan's > metadata is also supported, see ovs-fields for more details. > > Signed-off-by: William Tu <u9012...@gmail.com>
Thanks. Here is an incremental I suggest folding in. The changes to .c and .h files fix some unaligned access issues that Clang reported. --8<--------------------------cut here-------------------------->8-- diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h index 2c1be7f2ea16..64470b524495 100644 --- a/include/openvswitch/meta-flow.h +++ b/include/openvswitch/meta-flow.h @@ -454,27 +454,27 @@ enum OVS_PACKED_ENUM mf_field_id { * * ERSPAN index (direction/port number) * - * Type: be32. + * Type: be32 (low 20 bits). * Maskable: bitwise. * Formatting: hexadecimal. * Prerequisites: none. * Access: read/write. * NXM: none. - * OXM: NXOXM_ET_ERSPAN_IDX(11) since OF1.5 and v2.9. + * OXM: NXOXM_ET_ERSPAN_IDX(11) since OF1.5 and v2.10. */ MFF_TUN_ERSPAN_IDX, /* "tun_erspan_ver". * - * ERSPAN vsersion (v1 / v2) + * ERSPAN version (v1 / v2) * - * Type: u8. + * Type: u8 (low 4 bits). * Maskable: bitwise. * Formatting: decimal. * Prerequisites: none. * Access: read/write. * NXM: none. - * OXM: NXOXM_ET_ERSPAN_VER(12) since OF1.5 and v2.9. + * OXM: NXOXM_ET_ERSPAN_VER(12) since OF1.5 and v2.10. */ MFF_TUN_ERSPAN_VER, @@ -482,13 +482,13 @@ enum OVS_PACKED_ENUM mf_field_id { * * ERSPAN mirrored traffic's direction * - * Type: u8. + * Type: u8 (low 1 bits). * Maskable: bitwise. * Formatting: decimal. * Prerequisites: none. * Access: read/write. * NXM: none. - * OXM: NXOXM_ET_ERSPAN_DIR(13) since OF1.5 and v2.9. + * OXM: NXOXM_ET_ERSPAN_DIR(13) since OF1.5 and v2.10. */ MFF_TUN_ERSPAN_DIR, @@ -496,13 +496,13 @@ enum OVS_PACKED_ENUM mf_field_id { * * ERSPAN Hardware ID * - * Type: u8. + * Type: u8 (low 6 bits). * Maskable: bitwise. * Formatting: hexadecimal. * Prerequisites: none. * Access: read/write. * NXM: none. - * OXM: NXOXM_ET_ERSPAN_HWID(14) since OF1.5 and v2.9. + * OXM: NXOXM_ET_ERSPAN_HWID(14) since OF1.5 and v2.10. */ MFF_TUN_ERSPAN_HWID, diff --git a/lib/meta-flow.xml b/lib/meta-flow.xml index 8c7aa00ad769..144657c34422 100644 --- a/lib/meta-flow.xml +++ b/lib/meta-flow.xml @@ -1716,20 +1716,19 @@ ovs-ofctl add-flow br-int 'in_port=3,tun_src=192.168.1.1,tun_id=5001 actions=1' </dl> </field> - <h2>ERSPAN Metadata Fields FIXME</h2> + <h2>ERSPAN Metadata Fields</h2> <p> - These fields provide access to features in the ERSPAN tunneling - protocol. The ERSPAN header is defined in the draft <url - href="https://tools.ietf.org/html/draft-foschiano-erspan-03"/> + These fields provide access to features in the ERSPAN tunneling protocol + [ERSPAN], which has two major versions: version 1 (aka type II) and + version 2 (aka type III). + </p> + + <p> + Regardless of version, ERSPAN is encapsulated within a fixed 8-byte GRE + header that consists of a 4-byte GRE base header and a 4-byte sequence + number. The ERSPAN version 1 header format is: </p> - <field id="MFF_TUN_ERSPAN_VER" title="ERSPAN Version"> - <p> - ERSPAN version number. 1 for version 1 (type II) - or 2 for version 2 (type III). - </p> - </field> - <p> ERSPAN version 1 header format:</p> <diagram> <header name="GRE"> <bits name="..." above="16" width="0.4"/> @@ -1739,7 +1738,7 @@ ovs-ofctl add-flow br-int 'in_port=3,tun_src=192.168.1.1,tun_id=5001 actions=1' <header name="ERSPAN v1"> <bits name="ver" above="4" below="1" width="0.4"/> <bits name="..." above="18" width="0.4"/> - <bits name="session" above="10" below="tun_id" width="0.4"/> + <bits name="session" above="10" below="tun_id" width="0.5"/> <bits name="..." above="12" width="0.4"/> <bits name="idx" above="20" width="0.6"/> </header> @@ -1751,19 +1750,10 @@ ovs-ofctl add-flow br-int 'in_port=3,tun_src=192.168.1.1,tun_id=5001 actions=1' <dots/> </diagram> - <p> ERSPAN has a fixed 8-byte GRE header, including 4-byte GRE base header - another 4-byte sequence number. The ERSPAN's 10-bit session ID holds - the tunnel ID. + <p> + The ERSPAN version 2 header format is: </p> - <field id="MFF_TUN_ERSPAN_IDX" title="ERSPAN Index"> - <p> - ERSPAN index is a 20-bit index/port number associated with the ERSPAN - traffic's source port and direction (ingress/egress). This field is - platform dependent. - </p> - </field> - <p> ERSPAN version 2 header format:</p> <diagram> <header name="GRE"> <bits name="..." above="16" width="0.4"/> @@ -1773,8 +1763,8 @@ ovs-ofctl add-flow br-int 'in_port=3,tun_src=192.168.1.1,tun_id=5001 actions=1' <header name="ERSPAN v2"> <bits name="ver" above="4" below="2" width="0.4"/> <bits name="..." above="18" width="0.4"/> - <bits name="session" above="10" below="tun_id" width="0.4"/> - <bits name="timestamp" above="32" width=".4"/> + <bits name="session" above="10" below="tun_id" width="0.5"/> + <bits name="timestamp" above="32" width=".7"/> <bits name="..." above="22" width="0.4"/> <bits name="hwid" above="6" width="0.4"/> <bits name="dir" above="1" below="0/1" width="0.4"/> @@ -1788,17 +1778,23 @@ ovs-ofctl add-flow br-int 'in_port=3,tun_src=192.168.1.1,tun_id=5001 actions=1' <dots/> </diagram> + <field id="MFF_TUN_ERSPAN_VER" title="ERSPAN Version"> + ERSPAN version number: 1 for version 1, or 2 for version 2. + </field> + + <field id="MFF_TUN_ERSPAN_IDX" title="ERSPAN Index"> + This field is a 20-bit index/port number associated with the ERSPAN + traffic's source port and direction (ingress/egress). This field is + platform dependent. + </field> + <field id="MFF_TUN_ERSPAN_DIR" title="ERSPAN Direction"> - <p> - Specifies the ERSPAN v2 mirrored traffic's direction. - Value 1 for egress traffic, and value 0 for ingress traffic. - </p> + For ERSPAN v2, the mirrored traffic's direction: 0 for ingress traffic, 1 + for egress traffic. </field> + <field id="MFF_TUN_ERSPAN_HWID" title="ERSPAN Hardware ID"> - <p> - ERSPAN hardware ID is a 6-bit unique identifier of an - ERSPAN v2 engine within a system. - </p> + A 6-bit unique identifier of an ERSPAN v2 engine within a system. </field> <h2>Geneve Fields</h2> @@ -4606,6 +4602,13 @@ r r c c c. Computer Communications Review, October 2007. </dd> + <dt>ERSPAN</dt> + <dd> + M. Foschiano, K. Ghosh, M. Mehta, ``Cisco Systems' Encapsulated Remote + Switch Port Analyzer (ERSPAN),'' <url + href="https://tools.ietf.org/html/draft-foschiano-erspan-03"/>. + </dd> + <dt>EXT-56</dt> <dd> J. Tonsing, ``Permit one of a set of prerequisites to apply, e.g. don't diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index 7152f3e995c0..66eb18ef9b0d 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -556,15 +556,13 @@ netdev_erspan_pop_header(struct dp_packet *packet) tnl->erspan_ver = ersh->ver; if (ersh->ver == 1) { - ovs_be32 *index; - index = (ovs_be32 *)(ersh + 1); - tnl->erspan_idx = ntohl(*index); + ovs_16aligned_be32 *index = ALIGNED_CAST(ovs_16aligned_be32 *, + ersh + 1); + tnl->erspan_idx = ntohl(get_16aligned_be32(index)); tnl->flags |= FLOW_TNL_F_KEY; hlen = ulen + ERSPAN_GREHDR_LEN + sizeof *ersh + ERSPAN_V1_MDSIZE; } else if (ersh->ver == 2) { - struct erspan_md2 *md2; - - md2 = (struct erspan_md2 *)(ersh + 1); + struct erspan_md2 *md2 = ALIGNED_CAST(struct erspan_md2 *, ersh + 1); tnl->erspan_dir = md2->dir; tnl->erspan_hwid = get_hwid(md2); tnl->flags |= FLOW_TNL_F_KEY; @@ -597,21 +595,20 @@ netdev_erspan_push_header(const struct netdev *netdev, struct gre_base_hdr *greh; struct erspan_md2 *md2; int ip_tot_size; - ovs_be32 *seqno; greh = netdev_tnl_push_ip_header(packet, data->header, data->header_len, &ip_tot_size); /* update GRE seqno */ tnl_cfg = &dev->tnl_cfg; - seqno = (ovs_be32 *)(greh + 1); - *seqno = htonl(tnl_cfg->seqno++); + ovs_16aligned_be32 *seqno = (ovs_16aligned_be32 *) (greh + 1); + put_16aligned_be32(seqno, htonl(tnl_cfg->seqno++)); /* update v2 timestamp */ if (greh->protocol == htons(ETH_TYPE_ERSPAN2)) { ersh = ERSPAN_HDR(greh); - md2 = (struct erspan_md2 *)(ersh + 1); - md2->timestamp = get_erspan_ts(ERSPAN_100US); + md2 = ALIGNED_CAST(struct erspan_md2 *, ersh + 1); + put_16aligned_be32(&md2->timestamp, get_erspan_ts(ERSPAN_100US)); } return; } @@ -645,29 +642,25 @@ netdev_erspan_build_header(const struct netdev *netdev, } if (tnl_cfg->erspan_ver == 1) { - ovs_be32 *index; - greh->protocol = htons(ETH_TYPE_ERSPAN1); greh->flags = htons(GRE_SEQ); ersh->ver = 1; set_sid(ersh, sid); - index = (ovs_be32 *)(ersh + 1); - *index = htonl(tnl_cfg->erspan_idx); + put_16aligned_be32(ALIGNED_CAST(ovs_16aligned_be32 *, ersh + 1), + htonl(tnl_cfg->erspan_idx)); hlen = ERSPAN_GREHDR_LEN + sizeof *ersh + ERSPAN_V1_MDSIZE; } else if (tnl_cfg->erspan_ver == 2) { - struct erspan_md2 *md2; - greh->protocol = htons(ETH_TYPE_ERSPAN2); greh->flags = htons(GRE_SEQ); ersh->ver = 2; set_sid(ersh, sid); - md2 = (struct erspan_md2 *)(ersh + 1); + struct erspan_md2 *md2 = ALIGNED_CAST(struct erspan_md2 *, ersh + 1); md2->sgt = 0; /* security group tag */ md2->gra = 0; - md2->timestamp = 0; + put_16aligned_be32(&md2->timestamp, 0); set_hwid(md2, tnl_cfg->erspan_hwid); md2->dir = tnl_cfg->erspan_dir; diff --git a/lib/odp-util.c b/lib/odp-util.c index 4b54e599b8bd..fc842ee5533a 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -721,15 +721,13 @@ format_odp_tnl_push_header(struct ds *ds, struct ovs_action_push_tnl *data) ersh = ERSPAN_HDR(greh); if (ersh->ver == 1) { - const ovs_be32 *index; - - index = (const ovs_be32 *)(ersh + 1); + ovs_16aligned_be32 *index = ALIGNED_CAST(ovs_16aligned_be32 *, + ersh + 1); ds_put_format(ds, "erspan(ver=1,sid=0x%"PRIx16",idx=0x%"PRIx32")", - get_sid(ersh), ntohl(*index)); + get_sid(ersh), ntohl(get_16aligned_be32(index))); } else if (ersh->ver == 2) { - const struct erspan_md2 *md2; - - md2 = (const struct erspan_md2 *)(ersh + 1); + struct erspan_md2 *md2 = ALIGNED_CAST(struct erspan_md2 *, + ersh + 1); ds_put_format(ds, "erspan(ver=2,sid=0x%"PRIx16 ",dir=%"PRIu8",hwid=0x%"PRIx8")", get_sid(ersh), md2->dir, get_hwid(md2)); @@ -1603,10 +1601,9 @@ ovs_parse_tnl_push(const char *s, struct ovs_action_push_tnl *data) ((uint8_t *) options - (uint8_t *) greh); } else if (ovs_scan_len(s, &n, "erspan(ver=1,sid="SCNx16",idx=0x"SCNx32")", &sid, &erspan_idx)) { - ovs_be32 *index; - ersh = ERSPAN_HDR(greh); - index = (ovs_be32 *)(ersh + 1); + ovs_16aligned_be32 *index = ALIGNED_CAST(ovs_16aligned_be32 *, + ersh + 1); if (eth->eth_type == htons(ETH_TYPE_IP)) { tnl_type = OVS_VPORT_TYPE_ERSPAN; @@ -1619,7 +1616,7 @@ ovs_parse_tnl_push(const char *s, struct ovs_action_push_tnl *data) ersh->ver = 1; set_sid(ersh, sid); - *index = htonl(erspan_idx); + put_16aligned_be32(index, htonl(erspan_idx)); if (!ovs_scan_len(s, &n, ")")) { return -EINVAL; @@ -1631,7 +1628,7 @@ ovs_parse_tnl_push(const char *s, struct ovs_action_push_tnl *data) ",hwid=0x"SCNx8")", &sid, &dir, &hwid)) { ersh = ERSPAN_HDR(greh); - md2 = (struct erspan_md2 *)(ersh + 1); + md2 = ALIGNED_CAST(struct erspan_md2 *, ersh + 1); if (eth->eth_type == htons(ETH_TYPE_IP)) { tnl_type = OVS_VPORT_TYPE_ERSPAN; diff --git a/lib/packets.h b/lib/packets.h index 61888da599ef..7645a9de0be0 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1300,7 +1300,7 @@ struct erspan_base_hdr { }; struct erspan_md2 { - ovs_be32 timestamp; + ovs_16aligned_be32 timestamp; ovs_be16 sgt; uint8_t hwid_upper:2, ft:5, _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev