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;