From 4380c4abb979b4123c4abe5cc1d606421b035570 Mon Sep 17 00:00:00 2001 From: reyk Date: Wed, 20 Jul 2016 19:57:54 +0000 Subject: [PATCH] Parse and print OpenFlow 1.3 PACKET_IN and OXM (Openflow eXtended Match) - no action yet. --- usr.sbin/switchd/genmap.sh | 4 +- usr.sbin/switchd/ofp.h | 140 +++++++++++++++++++------------------ usr.sbin/switchd/ofp13.c | 79 +++++++++++++++++++-- usr.sbin/switchd/ofp_map.h | 5 +- 4 files changed, 151 insertions(+), 77 deletions(-) diff --git a/usr.sbin/switchd/genmap.sh b/usr.sbin/switchd/genmap.sh index 76ecee1497c..b10b335cabc 100644 --- a/usr.sbin/switchd/genmap.sh +++ b/usr.sbin/switchd/genmap.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: genmap.sh,v 1.1 2016/07/19 16:54:26 reyk Exp $ +# $OpenBSD: genmap.sh,v 1.2 2016/07/20 19:57:54 reyk Exp $ # Copyright (c) 2010-2013 Reyk Floeter # @@ -58,7 +58,7 @@ tok=$(echo ${TOKEN} | tr "[:upper:]" "[:lower:]") INC="#include ${HEADER}" MAP=$(grep "struct constmap ${tok}_" $MAPFILE | - sed -Ee "s/.*${tok}_([^_]+)_map.*/\1/g") + sed -Ee "s/.*${tok}_(.+)_map.*/\1/g") # Print license/copyright notice and headers cat < @@ -26,7 +26,9 @@ #include #include -#define OFP_IFNAMSIZ 16 /* on-wire (not IF_NAMSIZE) */ +#define OFP_IFNAMSIZ 16 /* on-wire (not IF_NAMSIZE) */ +#define OFP_ALIGNMENT 8 /* OFP alignment */ +#define OFP_ALIGN(_x) (((_x) + (OFP_ALIGNMENT - 1)) & ~(OFP_ALIGNMENT - 1)) struct ofp_header { uint8_t oh_version; /* OpenFlow version */ @@ -265,21 +267,21 @@ struct ofp_instruction_experimenter { /* Actions */ #define OFP_ACTION_OUTPUT 0 /* Output to switch port */ -#define OFP_ACTION_COPY_TTL_OUT 11 /* */ -#define OFP_ACTION_COPY_TTL_IN 12 /* */ -#define OFP_ACTION_SET_MPLS_TTL 15 /* */ -#define OFP_ACTION_DEC_MPLS_TTL 16 /* */ -#define OFP_ACTION_PUSH_VLAN 17 /* */ -#define OFP_ACTION_POP_VLAN 18 /* */ -#define OFP_ACTION_PUSH_MPLS 19 /* */ -#define OFP_ACTION_POP_MPLS 20 /* */ -#define OFP_ACTION_SET_QUEUE 21 /* */ -#define OFP_ACTION_GROUP 22 /* */ -#define OFP_ACTION_SET_NW_TTL 23 /* */ -#define OFP_ACTION_DEC_NW_TTL 24 /* */ -#define OFP_ACTION_SET_FIELD 25 /* */ -#define OFP_ACTION_PUSH_PBB 26 /* */ -#define OFP_ACTION_POP_PBB 27 /* */ +#define OFP_ACTION_COPY_TTL_OUT 11 /* ? */ +#define OFP_ACTION_COPY_TTL_IN 12 /* ? */ +#define OFP_ACTION_SET_MPLS_TTL 15 /* ? */ +#define OFP_ACTION_DEC_MPLS_TTL 16 /* ? */ +#define OFP_ACTION_PUSH_VLAN 17 /* ? */ +#define OFP_ACTION_POP_VLAN 18 /* ? */ +#define OFP_ACTION_PUSH_MPLS 19 /* ? */ +#define OFP_ACTION_POP_MPLS 20 /* ? */ +#define OFP_ACTION_SET_QUEUE 21 /* ? */ +#define OFP_ACTION_GROUP 22 /* ? */ +#define OFP_ACTION_SET_NW_TTL 23 /* ? */ +#define OFP_ACTION_DEC_NW_TTL 24 /* ? */ +#define OFP_ACTION_SET_FIELD 25 /* ? */ +#define OFP_ACTION_PUSH_PBB 26 /* ? */ +#define OFP_ACTION_POP_PBB 27 /* ? */ #define OFP_ACTION_EXPERIMENTER 0xffff /* Vendor-specific action */ /* Action Header */ @@ -353,64 +355,64 @@ struct ofp_packet_out { } __packed; /* Flow match fields for basic class */ -#define OFP_XM_T_IN_PORT 0 -#define OFP_XM_T_IN_PHY_PORT 1 -#define OFP_XM_T_META 2 -#define OFP_XM_T_ETH_DST 3 -#define OFP_XM_T_ETH_SRC 4 -#define OFP_XM_T_ETH_TYPE 5 -#define OFP_XM_T_VLAN_VID 6 -#define OFP_XM_T_VLAN_PCP 7 -#define OFP_XM_T_IP_DSCP 8 -#define OFP_XM_T_IP_ECN 9 -#define OFP_XM_T_IP_PROTO 10 -#define OFP_XM_T_IPV4_SRC 11 -#define OFP_XM_T_IPV4_DST 12 -#define OFP_XM_T_TCP_SRC 13 -#define OFP_XM_T_TCP_DST 14 -#define OFP_XM_T_UDP_SRC 15 -#define OFP_XM_T_UDP_DST 16 -#define OFP_XM_T_SCTP_SRC 17 -#define OFP_XM_T_SCTP_DST 18 -#define OFP_XM_T_ICMPV4_TYPE 19 -#define OFP_XM_T_ICMPV4_CODE 20 -#define OFP_XM_T_ARP_OP 21 -#define OFP_XM_T_ARP_SPA 22 -#define OFP_XM_T_ARP_TPA 23 -#define OFP_XM_T_ARP_SHA 24 -#define OFP_XM_T_ARP_THA 25 -#define OFP_XM_T_IPV6_SRC 26 -#define OFP_XM_T_IPV6_DST 27 -#define OFP_XM_T_IPV6_FLABEL 28 -#define OFP_XM_T_ICMPV6_TYPE 29 -#define OFP_XM_T_ICMPV6_CODE 30 -#define OFP_XM_T_IPV6_ND_TARGET 31 -#define OFP_XM_T_IPV6_ND_SLL 32 -#define OFP_XM_T_IPV6_ND_TLL 33 -#define OFP_XM_T_MPLS_LABEL 34 -#define OFP_XM_T_MPLS_TC 35 -#define OFP_XM_T_MPLS_BOS 36 -#define OFP_XM_T_PBB_ISID 37 -#define OFP_XM_T_TUNNEL_ID 38 -#define OFP_XM_T_IPV6_EXTHDR 39 -#define OFP_XM_T_MAX 40 +#define OFP_XM_T_IN_PORT 0 /* ? */ +#define OFP_XM_T_IN_PHY_PORT 1 /* ? */ +#define OFP_XM_T_META 2 /* ? */ +#define OFP_XM_T_ETH_DST 3 /* ? */ +#define OFP_XM_T_ETH_SRC 4 /* ? */ +#define OFP_XM_T_ETH_TYPE 5 /* ? */ +#define OFP_XM_T_VLAN_VID 6 /* ? */ +#define OFP_XM_T_VLAN_PCP 7 /* ? */ +#define OFP_XM_T_IP_DSCP 8 /* ? */ +#define OFP_XM_T_IP_ECN 9 /* ? */ +#define OFP_XM_T_IP_PROTO 10 /* ? */ +#define OFP_XM_T_IPV4_SRC 11 /* ? */ +#define OFP_XM_T_IPV4_DST 12 /* ? */ +#define OFP_XM_T_TCP_SRC 13 /* ? */ +#define OFP_XM_T_TCP_DST 14 /* ? */ +#define OFP_XM_T_UDP_SRC 15 /* ? */ +#define OFP_XM_T_UDP_DST 16 /* ? */ +#define OFP_XM_T_SCTP_SRC 17 /* ? */ +#define OFP_XM_T_SCTP_DST 18 /* ? */ +#define OFP_XM_T_ICMPV4_TYPE 19 /* ? */ +#define OFP_XM_T_ICMPV4_CODE 20 /* ? */ +#define OFP_XM_T_ARP_OP 21 /* ? */ +#define OFP_XM_T_ARP_SPA 22 /* ? */ +#define OFP_XM_T_ARP_TPA 23 /* ? */ +#define OFP_XM_T_ARP_SHA 24 /* ? */ +#define OFP_XM_T_ARP_THA 25 /* ? */ +#define OFP_XM_T_IPV6_SRC 26 /* ? */ +#define OFP_XM_T_IPV6_DST 27 /* ? */ +#define OFP_XM_T_IPV6_FLABEL 28 /* ? */ +#define OFP_XM_T_ICMPV6_TYPE 29 /* ? */ +#define OFP_XM_T_ICMPV6_CODE 30 /* ? */ +#define OFP_XM_T_IPV6_ND_TARGET 31 /* ? */ +#define OFP_XM_T_IPV6_ND_SLL 32 /* ? */ +#define OFP_XM_T_IPV6_ND_TLL 33 /* ? */ +#define OFP_XM_T_MPLS_LABEL 34 /* ? */ +#define OFP_XM_T_MPLS_TC 35 /* ? */ +#define OFP_XM_T_MPLS_BOS 36 /* ? */ +#define OFP_XM_T_PBB_ISID 37 /* ? */ +#define OFP_XM_T_TUNNEL_ID 38 /* ? */ +#define OFP_XM_T_IPV6_EXTHDR 39 /* ? */ +#define OFP_XM_T_MAX 40 /* ? */ /* Flow match fields for nxm1 class */ -#define OFP_XM_NXMT_TUNNEL_ID 38 -#define OFP_XM_NXMT_TUNNEL_IPV4_SRC 31 -#define OFP_XM_NXMT_TUNNEL_IPV4_DST 32 -#define OFP_XM_NXMT_TUNNEL_IPV6_SRC 109 -#define OFP_XM_NXMT_TUNNEL_IPV6_DST 110 +#define OFP_XM_NXMT_TUNNEL_ID 38 /* ? */ +#define OFP_XM_NXMT_TUNNEL_IPV4_SRC 31 /* ? */ +#define OFP_XM_NXMT_TUNNEL_IPV4_DST 32 /* ? */ +#define OFP_XM_NXMT_TUNNEL_IPV6_SRC 109 /* ? */ +#define OFP_XM_NXMT_TUNNEL_IPV6_DST 110 /* ? */ /* OXM class */ -#define OFP_OXM_C_NXM_0 0x0000 -#define OFP_OXM_C_NXM_1 0x0001 -#define OFP_OXM_C_OPENFLOW_BASIC 0x8000 -#define OFP_OXM_C_OPENFLOW_EXPERIMENTER 0xffff +#define OFP_OXM_C_NXM_0 0x0000 /* NXM 0 */ +#define OFP_OXM_C_NXM_1 0x0001 /* NXM 1 */ +#define OFP_OXM_C_OPENFLOW_BASIC 0x8000 /* OpenFlow Basic */ +#define OFP_OXM_C_OPENFLOW_EXPERIMENTER 0xffff /* OpenFlow Experimenter */ /* VLAN matching flag */ -#define OFP_XM_VID_PRESENT 0x1000 -#define OFP_XM_VID_NONE 0x0000 +#define OFP_XM_VID_PRESENT 0x1000 /* VLAN ID present */ +#define OFP_XM_VID_NONE 0x0000 /* No VLAN ID */ struct ofp_ox_match { uint16_t oxm_class; diff --git a/usr.sbin/switchd/ofp13.c b/usr.sbin/switchd/ofp13.c index 8c850a52e67..9403f635e13 100644 --- a/usr.sbin/switchd/ofp13.c +++ b/usr.sbin/switchd/ofp13.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofp13.c,v 1.2 2016/07/20 14:15:08 reyk Exp $ */ +/* $OpenBSD: ofp13.c,v 1.3 2016/07/20 19:57:54 reyk Exp $ */ /* * Copyright (c) 2013-2016 Reyk Floeter @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -55,6 +56,8 @@ void ofp13_debug(struct switchd *, void ofp13_debug_header(struct switchd *, struct sockaddr_storage *, struct sockaddr_storage *, struct ofp_header *); +int ofp13_debug_oxm(struct switchd *, struct ofp_ox_match *, + struct ofp_header *, struct ibuf *, off_t); int ofp13_debug_packet_in(struct switchd *, struct sockaddr_storage *, struct sockaddr_storage *, struct ofp_header *, struct ibuf *); @@ -131,15 +134,55 @@ ofp13_debug(struct switchd *sc, log_debug("\tinvalid packet"); } +int +ofp13_debug_oxm(struct switchd *sc, struct ofp_ox_match *oxm, + struct ofp_header *oh, struct ibuf *ibuf, off_t off) +{ + uint16_t class; + uint8_t type; + uint32_t port; + void *ptr; + + /* match element is always followed by data */ + if (oxm->oxm_length == 0) + return (0); + + type = OFP_OXM_GET_FIELD(oxm); + class = ntohs(oxm->oxm_class); + + log_debug("\tox match class %s type %s length %u", + print_map(class, ofp_oxm_map), + print_map(type, ofp_xm_t_map), + oxm->oxm_length); + + switch (class) { + case OFP_OXM_C_OPENFLOW_BASIC: + switch (type) { + case OFP_XM_T_IN_PORT: + off += sizeof(*oxm); + if ((ptr = ibuf_seek(ibuf, off, sizeof(port))) == NULL) + return (-1); + port = *(uint32_t *)ptr; + log_debug("\t\tport %u", ntohl(port)); + break; + } + break; + } + + return (0); +} + int ofp13_debug_packet_in(struct switchd *sc, struct sockaddr_storage *src, struct sockaddr_storage *dst, struct ofp_header *oh, struct ibuf *ibuf) { struct ofp_packet_in *pin; + struct ofp_match *om; + struct ofp_ox_match *oxm; uint8_t *p; - size_t len; - off_t off; + ssize_t len, mlen; + off_t moff, off; off = 0; if ((pin = ibuf_seek(ibuf, off, sizeof(*pin))) == NULL) @@ -150,8 +193,36 @@ ofp13_debug_packet_in(struct switchd *sc, print_map(ntohs(pin->pin_reason), ofp_pktin_map), pin->pin_table_id, be64toh(pin->pin_cookie)); + off += offsetof(struct ofp_packet_in, pin_match); + + om = &pin->pin_match; + mlen = ntohs(om->om_length); + log_debug("\tmatch type %s length %zu (padded to %zu)", + print_map(ntohs(om->om_type), ofp_match_map), + mlen, OFP_ALIGN(mlen) + ETHER_ALIGN); + + /* current match offset, aligned offset after all matches */ + moff = off + sizeof(*om); + off += OFP_ALIGN(mlen) + ETHER_ALIGN; + + switch (htons(om->om_type)) { + case OFP_MATCH_OXM: + do { + if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL) + return (-1); + if (ofp13_debug_oxm(sc, oxm, oh, ibuf, moff) == -1) + return (-1); + moff += sizeof(*oxm) + oxm->oxm_length; + mlen -= sizeof(*oxm) + oxm->oxm_length; + } while (mlen > 0 && oxm->oxm_length); + break; + case OFP_MATCH_STANDARD: + /* deprecated */ + break; + } + + /* Calculate offset from the beginning */ len = ntohs(pin->pin_total_len); - off += sizeof(*pin); if ((p = ibuf_seek(ibuf, off, len)) == NULL) return (-1); if (sc->sc_tap != -1) diff --git a/usr.sbin/switchd/ofp_map.h b/usr.sbin/switchd/ofp_map.h index a9613abd6e0..63d3b30a6b9 100644 --- a/usr.sbin/switchd/ofp_map.h +++ b/usr.sbin/switchd/ofp_map.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ofp_map.h,v 1.2 2016/07/20 14:15:08 reyk Exp $ */ +/* $OpenBSD: ofp_map.h,v 1.3 2016/07/20 19:57:54 reyk Exp $ */ /* * Copyright (c) 2013-2016 Reyk Floeter @@ -37,9 +37,10 @@ extern struct constmap ofp10_errflowmod_map[]; /* OpenFlow 1.3+ maps */ extern struct constmap ofp_v_map[]; extern struct constmap ofp_t_map[]; -extern struct constmap ofp_hi_map[]; extern struct constmap ofp_pktin_map[]; extern struct constmap ofp_port_map[]; +extern struct constmap ofp_oxm_map[]; +extern struct constmap ofp_xm_t_map[]; extern struct constmap ofp_config_map[]; extern struct constmap ofp_portstate_map[]; extern struct constmap ofp_portconfig_map[]; -- 2.20.1