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;

Reply via email to