This diff adds the missing IP_PROTO oxm validation and adds more hasmask checks for types that should not have that.
ok? Index: ofp13.c =================================================================== RCS file: /cvs/src/usr.sbin/switchd/ofp13.c,v retrieving revision 1.29 diff -u -p -r1.29 ofp13.c --- ofp13.c 17 Nov 2016 16:24:00 -0000 1.29 +++ ofp13.c 17 Nov 2016 17:46:32 -0000 @@ -183,6 +183,8 @@ ofp13_validate_oxm_basic(struct ibuf *ib case OFP_XM_T_IN_PORT: case OFP_XM_T_IN_PHY_PORT: case OFP_XM_T_MPLS_LABEL: + if (hasmask) + return (-1); if ((ui32 = ibuf_seek(ibuf, off, sizeof(*ui32))) == NULL) return (-1); @@ -205,12 +207,26 @@ ofp13_validate_oxm_basic(struct ibuf *ib log_debug("\t\t%llu", be64toh(*ui64)); break; - case OFP_XM_T_ETH_DST: - case OFP_XM_T_ETH_SRC: case OFP_XM_T_ARP_SHA: case OFP_XM_T_ARP_THA: case OFP_XM_T_IPV6_ND_SLL: case OFP_XM_T_IPV6_ND_TLL: + if (hasmask) + return (-1); + if ((ui8 = ibuf_seek(ibuf, off, ETHER_ADDR_LEN)) == NULL) + return (-1); + + buf[0] = 0; + for (i = 0; i < ETHER_ADDR_LEN; i++) { + snprintf(hex, sizeof(hex), "%02x", *(ui8 + i)); + strlcat(buf, hex, sizeof(buf)); + } + + log_debug("\t\t%s", buf); + break; + + case OFP_XM_T_ETH_DST: + case OFP_XM_T_ETH_SRC: len = ETHER_ADDR_LEN; if (hasmask) len *= 2; @@ -245,15 +261,22 @@ ofp13_validate_oxm_basic(struct ibuf *ib log_debug("\t\t0x%04x", ntohs(*ui16)); break; - case OFP_XM_T_ARP_OP: - case OFP_XM_T_VLAN_VID: - case OFP_XM_T_IP_PROTO: case OFP_XM_T_TCP_SRC: case OFP_XM_T_TCP_DST: case OFP_XM_T_UDP_SRC: case OFP_XM_T_UDP_DST: case OFP_XM_T_SCTP_SRC: case OFP_XM_T_SCTP_DST: + case OFP_XM_T_ARP_OP: + if (hasmask) + return (-1); + if ((ui16 = ibuf_seek(ibuf, off, sizeof(*ui16))) == NULL) + return (-1); + + log_debug("\t\t%d", ntohs(*ui16)); + break; + + case OFP_XM_T_VLAN_VID: case OFP_XM_T_IPV6_EXTHDR: len = sizeof(*ui16); if (hasmask) @@ -283,12 +306,15 @@ ofp13_validate_oxm_basic(struct ibuf *ib case OFP_XM_T_IP_DSCP: case OFP_XM_T_IP_ECN: + case OFP_XM_T_IP_PROTO: case OFP_XM_T_ICMPV4_TYPE: case OFP_XM_T_ICMPV4_CODE: case OFP_XM_T_ICMPV6_TYPE: case OFP_XM_T_ICMPV6_CODE: case OFP_XM_T_MPLS_TC: case OFP_XM_T_MPLS_BOS: + if (hasmask) + return (-1); if ((ui8 = ibuf_seek(ibuf, off, sizeof(*ui8))) == NULL) return (-1); @@ -314,9 +340,24 @@ ofp13_validate_oxm_basic(struct ibuf *ib log_debug("\t\t%#08x", ntohl(*ui32)); break; + case OFP_XM_T_IPV6_ND_TARGET: + if (hasmask) + return (-1); + if ((ui8 = ibuf_seek(ibuf, off, + sizeof(struct in6_addr))) == NULL) + return (-1); + + buf[0] = 0; + for (i = 0; i < (int)sizeof(struct in6_addr); i++) { + snprintf(hex, sizeof(hex), "%02x", *(ui8 + i)); + strlcat(buf, hex, sizeof(buf)); + } + + log_debug("\t\t%s", buf); + break; + case OFP_XM_T_IPV6_SRC: case OFP_XM_T_IPV6_DST: - case OFP_XM_T_IPV6_ND_TARGET: len = sizeof(struct in6_addr); if (hasmask) len *= 2;