コード例 #1
0
ファイル: cnode.c プロジェクト: D-TOKIOKA/lagopus
/* Perform name match against the schema.  Result is stored in
 * match_type. */
void
cnode_schema_match(struct cnode *schema, char *name,
                   enum match_type *match_type) {
  switch (schema->type) {
    case CNODE_TYPE_KEYWORD:
      keyword_match(name, schema->name, match_type);
      break;
    case CNODE_TYPE_WORD:
      word_match(name, match_type);
      break;
    case CNODE_TYPE_IPV4:
      ipv4_match(name, match_type);
      break;
    case CNODE_TYPE_IPV4_PREFIX:
      ipv4_prefix_match(name, match_type);
      break;
    case CNODE_TYPE_IPV6:
      ipv6_match(name, match_type);
      break;
    case CNODE_TYPE_IPV6_PREFIX:
      ipv6_prefix_match(name, match_type);
      break;
    case CNODE_TYPE_MAC:
      mac_address_match(name, match_type);
      break;
    case CNODE_TYPE_RANGE:
      range_match(name, schema, match_type);
      break;
    default:
      *match_type = NONE_MATCH;
      break;
  }
}
コード例 #2
0
bool
match_std_nonstrict(struct ofl_match *a, struct ofl_match *b) {
  
struct ofl_match_tlv *flow_mod_match; 
    struct ofl_match_tlv *flow_entry_match;
    bool ret = false;

    /*Matches all flows */
    if(!a->header.length )
        return true;
    
    /* Loop through the match fields */
    HMAP_FOR_EACH(flow_mod_match, struct ofl_match_tlv, hmap_node, &a->match_fields){
       /* Check if the field is present in the flow entry */
        HMAP_FOR_EACH_WITH_HASH(flow_entry_match, struct ofl_match_tlv, hmap_node, hash_int(flow_mod_match->header, 0), &b->match_fields){                  
                int field_len =  OXM_LENGTH(flow_mod_match->header);
                bool has_mask;
                /* Check if both fields have or not a mask */
                if ( (OXM_HASMASK(flow_mod_match->header) && !OXM_HASMASK(flow_entry_match->header))
                    || (!OXM_HASMASK(flow_mod_match->header) && OXM_HASMASK(flow_entry_match->header))){
                    return false;
                }
                ret = true;
                has_mask = OXM_HASMASK(flow_mod_match->header);
                switch (field_len){
                    case (sizeof(uint8_t)):{
                        if (has_mask){
                            if (nonstrict_mask8(flow_mod_match->value, flow_entry_match->value + field_len, flow_entry_match->value,flow_entry_match->value + field_len) == 0){
                              return false;
                            }
                        }
                        else 
                            if (matches_8(flow_mod_match->value, flow_entry_match->value) == 0){
                              return false;
                        }
                        break;   
                    }
                    case (sizeof(uint16_t)):{ 
                        if (has_mask){
                            if (nonstrict_mask16(flow_mod_match->value,flow_entry_match->value + field_len, flow_entry_match->value,flow_entry_match->value + field_len) == 0){
                              return false;
                            }
                        }
                        else 
                            if (matches_16(flow_mod_match->value, flow_entry_match->value) == 0){
                              return false;
                        }
                        break;
                    } 
                    case (sizeof(uint32_t)):{ 
                        
                        if (has_mask){
                            if (nonstrict_mask32(flow_mod_match->value,flow_entry_match->value + field_len, flow_entry_match->value,flow_entry_match->value + field_len) ){
                              return false;
                            }
                        }
                        else 
                            if (matches_32(flow_mod_match->value, flow_entry_match->value) == 0){
                              return false;
                            }
                        break;
                    }
                    case (ETH_ADDR_LEN):{ 
                         if (has_mask){
                            if (nonstrict_ethaddr(flow_mod_match->value,flow_entry_match->value + field_len, flow_entry_match->value,flow_entry_match->value + field_len) == 0){
                              return false;
                            }
                         }
                        else 
                            if (eth_match(flow_mod_match->value, flow_entry_match->value) == 0){
                              return false;
                            }
                        break;
                    }
                    case (sizeof(uint64_t)):{ 
                        if (has_mask) {
                            if (nonstrict_mask64(flow_mod_match->value,flow_entry_match->value + field_len, flow_entry_match->value,flow_entry_match->value + field_len) == 0){
                              return false;
                            }
                        }
                        else 
                            if (matches_64(flow_mod_match->value, flow_entry_match->value) == 0){
                              return false;
                            }
                        break;
                    }
   		            case (16):{
                        if (has_mask){
                            if (nonstrict_ipv6(flow_mod_match->value,flow_entry_match->value + field_len, flow_entry_match->value,flow_entry_match->value + field_len)== 0){
                              return false;
                            }
                        }
                        else 
                            if (ipv6_match(flow_mod_match->value, flow_entry_match->value) == 0){
                              return false;
                            }
                        break;
                    }
 
            }
           
        }
         if (!ret)
            return ret;
        else ret = false;
    } 
    return true;

}
コード例 #3
0
bool 
packet_match(struct ofl_match *flow_match, struct ofl_match *packet){

    struct ofl_match_tlv *f; 
    struct packet_fields *packet_f;
    bool ret = false;

    if (flow_match->header.length == 0){
        return true;
    }

    /* Loop through the match fields */
    HMAP_FOR_EACH(f, struct ofl_match_tlv, hmap_node, &flow_match->match_fields){
        /* Check if the field is present in the packet */
        // HMAP_FOR_EACH_WITH_HASH(packet_f, struct packet_fields, hmap_node, hash_int(f->header, 0), &packet->match_fields){ 
        HMAP_FOR_EACH(packet_f, struct packet_fields, hmap_node, &packet->match_fields){ 
            if (OXM_TYPE(f->header) == OXM_TYPE(packet_f->header)) {
                int field_len =  OXM_LENGTH(f->header);
                bool has_mask = OXM_HASMASK(f->header);
                ret = true;
                if (has_mask)
                {
                    field_len = field_len/2;
                }
                switch (field_len){
                    case (sizeof(uint8_t)):{
                        if (has_mask){
                            if (pkt_mask8(f->value,f->value + field_len, packet_f->value) == 0){
                              return false;
                            }
                        }
                        else 
                            if (matches_8(f->value, packet_f->value) == 0){
                              return false;
                        }
                        break;   
                    }
                    case (sizeof(uint16_t)):{
                        if (OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_VLAN_VID)) {
                        	if (*((uint16_t*)f->value) == OFPVID_NONE)
                        		return false; // we have vlan tag when we expect none
                        	else if (*((uint16_t*)f->value) == OFPVID_PRESENT && has_mask)
                        		break; // this is the case where each vlan is a match
                        	else
                        		*((uint16_t*)f->value) &= VLAN_VID_MASK; // remove CFI bit
                        }

                        if (OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_IPV6_EXTHDR)){
                            if (ipv6_eh_match(f->value, packet_f->value) == 0) {
                                return false;
                            }
                        }
                        else if (has_mask){
                            if (pkt_mask16(f->value,f->value+ field_len, packet_f->value) == 0){
                              return false;
                            }
                        }
                        else {
                            if (pkt_match_16(f->value, packet_f->value) == 0){
                              return false;
                            }
                        }
                        break;
                    } 
                    case (sizeof(uint32_t)):{ 
                        if (has_mask){
                            if (OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_IPV4_DST) || OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_IPV4_SRC)
							    || OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_ARP_SPA) || OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_ARP_TPA)){
							    if (matches_mask32(f->value,f->value + field_len, packet_f->value) == 0){
                                     return false;
                                }
                            }     
                            else 
                                if (pkt_mask32(f->value,f->value + field_len, packet_f->value) == 0){
                                    return false;
                            }
                        }
                        else
                            if (OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_IPV4_DST) || OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_IPV4_SRC)
							    ||OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_ARP_SPA) || OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_ARP_TPA)){
							    if (matches_32(f->value, packet_f->value) == 0){
                                     return false;
                                }
                            }
                            else {
                                if (pkt_match_32(f->value, packet_f->value) == 0){
                                    return false;
                                }
                            }    
                        break;
                    }
                    case (ETH_ADDR_LEN):{ 
                         if (has_mask){
                            if (eth_mask(f->value,f->value + field_len, packet_f->value) == 0){
                              return false;
                            }
                         }
                        else 
                            if (eth_match(f->value, packet_f->value) == 0){
                              return false;
                            }
                        break;
                    }
                    case (sizeof(uint64_t)):{ 
                        if (has_mask) {
                            if (pkt_mask64(f->value,f->value + field_len, packet_f->value) == 0){
                              return false;
                            }
                        }
                        else 
                            if (matches_64(f->value, packet_f->value) == 0){
                              return false;
                            }
                        break;
                    }
   		            case (16):{
                        if (has_mask){
                            if (ipv6_mask(f->value,f->value + field_len, packet_f->value) == 0){
                              
                              return false;
                            }
                        }
                        else 
                            if (ipv6_match(f->value, packet_f->value) == 0){
                              return false;
                            }
                        break;
                    }
                } // end of switch case
            } // end of if (OXM_TYPE(f->header) == OXM_TYPE(packet_f->header))
        } // end of packet_match loop
        if (OXM_TYPE(f->header) == OXM_TYPE(OXM_OF_VLAN_VID))
        	if (*((uint16_t*)f->value) == OFPVID_NONE)
        		ret = true; // in case the packet has no vlan and this is what was expected

        if (!ret)
           return ret;
        else ret = false;
    } // end of flow_match loop

    return true;

}
コード例 #4
0
bool 
packet_match(struct ofl_match *flow_match, struct ofl_match *packet){

    struct ofl_match_tlv *f; 
    struct packet_fields *packet_f;
    bool ret = false;

    if (flow_match->header.length == 0){
        return true;
    }
    /*TODO: Possible combinations of VLAN_ID and masks */
    HMAP_FOR_EACH_WITH_HASH(f, struct ofl_match_tlv, hmap_node,hash_int(OXM_OF_VLAN_VID, 0), &flow_match->match_fields){
        uint16_t *matchv = (uint16_t*) f->value;
        /* Check if the field is present in the packet */
        HMAP_FOR_EACH_WITH_HASH(packet_f, struct packet_fields, hmap_node, hash_int(OXM_OF_VLAN_VID, 0), &packet->match_fields){     
            /* Do not match packets with a VLAN Tag */
            if (*matchv == OFPVID_NONE && !OXM_HASMASK(f->header))
                return false;
            ret = true;
        }

        if ((*matchv == OFPVID_PRESENT)  & (OXM_HASMASK(f->header))){
            uint16_t *maskv = (uint16_t*) f->value + 2;
                if (*maskv == OFPVID_PRESENT && !ret )
                    return false;     
        }
          
    }      

    /* Loop through the match fields */
    HMAP_FOR_EACH(f, struct ofl_match_tlv, hmap_node, &flow_match->match_fields){
        /* Check if the field is present in the packet */
        HMAP_FOR_EACH_WITH_HASH(packet_f, struct packet_fields, hmap_node, hash_int(f->header, 0), &packet->match_fields){ 
                int field_len =  OXM_LENGTH(f->header);
                bool has_mask = OXM_HASMASK(f->header);
                ret = true;
                switch (field_len){
                    case (sizeof(uint8_t)):{
                        if (has_mask){
                            if (pkt_mask8(f->value,f->value + field_len, packet_f->value) == 0){
                              return false;
                            }
                        }
                        else 
                            if (matches_8(f->value, packet_f->value) == 0){
                              return false;
                        }
                        break;   
                    }
                    case (sizeof(uint16_t)):{
                        if (has_mask){
                            if (pkt_mask16(f->value,f->value+ field_len, packet_f->value) == 0){
                              return false;
                            }
                        }
                        else {
                            if (pkt_match_16(f->value, packet_f->value) == 0){
                              return false;
                            }
                        }
                        break;
                    } 
                    case (sizeof(uint32_t)):{ 
                        if (has_mask){
                            if (f->header == OXM_OF_IPV4_DST || f->header == OXM_OF_IPV4_SRC
							    ||f->header == OXM_OF_ARP_SPA || f->header == OXM_OF_ARP_TPA){
							    if (matches_mask32(f->value,f->value + field_len, packet_f->value) == 0){
                                     return false;
                                }
                            }     
                            else 
                                if (pkt_mask32(f->value,f->value + field_len, packet_f->value) == 0){
                                    return false;
                            }
                        }
                        else
                            if (f->header == OXM_OF_IPV4_DST || f->header == OXM_OF_IPV4_SRC
							    ||f->header == OXM_OF_ARP_SPA || f->header == OXM_OF_ARP_TPA){
							    if (matches_32(f->value, packet_f->value) == 0){
                                     return false;
                                }
                            }
                            
                            else 
                                if (pkt_match_32(f->value, packet_f->value) == 0){
                                    return false;
                            }
                        break;
                    }
                    case (ETH_ADDR_LEN):{ 
                         if (has_mask){
                            if (eth_mask(f->value,f->value + field_len, packet_f->value) == 0){
                              return false;
                            }
                         }
                        else 
                            if (eth_match(f->value, packet_f->value) == 0){
                              return false;
                            }
                        break;
                    }
                    case (sizeof(uint64_t)):{ 
                        if (has_mask) {
                            if (pkt_mask64(f->value,f->value + field_len, packet_f->value) == 0){
                              return false;
                            }
                        }
                        else 
                            if (matches_64(f->value, packet_f->value) == 0){
                              return false;
                            }
                        break;
                    }
   		            case (16):{
                        if (has_mask){
                            if (ipv6_mask(f->value,f->value + field_len, packet_f->value) == 0){
                              return false;
                            }
                        }
                        else 
                            if (ipv6_match(f->value, packet_f->value) == 0){
                              return false;
                            }
                        break;
                    }
               
            }
        }
         if (!ret)
            return ret;
         else ret = false;      
    }

    return true;

}
コード例 #5
0
ファイル: cnode.c プロジェクト: D-TOKIOKA/lagopus
struct cnode *
cnode_match(struct cnode *cnode, char *name) {
  uint32_t i;
  struct cnode *child;
  enum match_type type;

  if (cnode == NULL) {
    return NULL;
  }

  for (i = 0; i < vector_max(cnode->v); i++) {
    if ((child = vector_slot(cnode->v, i)) != NULL) {
      switch (child->type) {
        case CNODE_TYPE_KEYWORD:
          if (strcmp(child->name, name) == 0) {
            return child;
          }
          break;
        case CNODE_TYPE_WORD:
          return child;
          break;
        case CNODE_TYPE_IPV4:
          ipv4_match(name, &type);
          if (type == IPV4_MATCH) {
            return child;
          }
          break;
        case CNODE_TYPE_IPV4_PREFIX:
          ipv4_prefix_match(name, &type);
          if (type == IPV4_PREFIX_MATCH) {
            return child;
          }
          break;
        case CNODE_TYPE_IPV6:
          ipv6_match(name, &type);
          if (type == IPV6_MATCH) {
            return child;
          }
          break;
        case CNODE_TYPE_IPV6_PREFIX:
          ipv6_prefix_match(name, &type);
          if (type == IPV6_PREFIX_MATCH) {
            return child;
          }
          break;
        case CNODE_TYPE_MAC:
          mac_address_match(name, &type);
          if (type == MAC_ADDRESS_MATCH) {
            return child;
          }
          break;
        case CNODE_TYPE_RANGE:
          range_match(name, child, &type);
          if (type == RANGE_MATCH) {
            return child;
          }
          break;
        default:
          break;
      }
    }
  }
  return NULL;
}