:: # Copyright 2014, Big Switch Networks, Inc.
:: #
:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
:: # the following special exception:
:: #
:: # LOXI Exception
:: #
:: # As a special exception to the terms of the EPL, you may distribute libraries
:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
:: # from the LoxiGen Libraries and the notice provided below is (i) included in
:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
:: # documentation for the LoxiGen Libraries, if distributed in binary form.
:: #
:: # Notice: "Copyright 2014, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
:: #
:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
:: # a copy of the EPL at:
:: #
:: # http://www.eclipse.org/legal/epl-v10.html
:: #
:: # Unless required by applicable law or agreed to in writing, software
:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
:: # EPL for the specific language governing permissions and limitations
:: # under the EPL.
::
:: include('_copyright.c')
:: import loxi_globals
:: from loxi_ir import *

/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Source file for OpenFlow message validation.
 *
 */

#include "loci_log.h"
#include <loci/loci.h>
#include <loci/loci_validator.h>

#define VALIDATOR_LOG(...) LOCI_LOG_ERROR("Validator Error: " __VA_ARGS__)

:: raw_validator_name = lambda cls, version: "loci_validate_%s_%s" % (cls, version.constant_version(prefix='OF_VERSION_'))
:: validator_name = lambda ofclass: "loci_validate_%s_%s" % (ofclass.name, ofclass.protocol.version.constant_version(prefix='OF_VERSION_'))

/* Forward declarations */
:: for version, proto in loxi_globals.ir.items():
:: for ofclass in proto.classes:
static int __attribute__((unused)) ${validator_name(ofclass)}(uint8_t *data, int len, int *out_len);
:: #endfor
:: #endfor

:: readers = { 1: 'buf_u8_get', 2: 'buf_u16_get', 4: 'buf_u32_get' }
:: types = { 1: 'uint8_t', 2: 'uint16_t', 4: 'uint32_t' }

:: for version, proto in loxi_globals.ir.items():

:: # Identify classes in lists and generate list validators
:: seen_lists = set()
:: for ofclass in proto.classes:
:: for m in ofclass.members:
:: if type(m) == OFDataMember and m.oftype.startswith('list'):
:: element_name = m.oftype[8:-3]
:: if element_name in seen_lists:
:: continue
:: #endif
:: seen_lists.add(element_name)
:: list_validator_name = raw_validator_name('of_list_' + element_name, version)
static int __attribute__((unused))
${list_validator_name}(uint8_t *data, int len, int *out_len)
{
    while (len > 0) {
        int cur_len = 0xffff;
        if (${raw_validator_name('of_' + element_name, version)}(data, len, &cur_len) < 0) {
            return -1;
        }
        len -= cur_len;
        data += cur_len;
    }

    return 0;
}

:: #endif
:: #endfor
:: #endfor

:: for ofclass in proto.classes:
static int
${validator_name(ofclass)}(uint8_t *data, int len, int *out_len)
{
    if (len < ${ofclass.base_length}) {
        return -1;
    }

:: if ofclass.is_fixed_length:
    len = ${ofclass.base_length};
:: #endif

:: # Read and validate length fields
:: field_length_members = {}
:: for m in ofclass.members:
:: if type(m) == OFLengthMember:
    ${types[m.length]} wire_len;
    ${readers[m.length]}(data + ${m.offset}, &wire_len);
    if (wire_len > len || wire_len < ${ofclass.base_length}) {
        return -1;
    }

    len = wire_len;
:: elif type(m) == OFFieldLengthMember:
:: field_length_members[m.field_name] = m
:: #endif
:: #endfor

:: # Dispatch to subclass validators
:: if ofclass.virtual:
:: discriminator = ofclass.discriminator
    ${types[discriminator.length]} wire_type;
    ${readers[discriminator.length]}(data + ${discriminator.offset}, &wire_type);
    switch (wire_type) {
:: for subclass in proto.classes:
:: if subclass.superclass == ofclass:
    case ${subclass.member_by_name(discriminator.name).value}:
        return ${validator_name(subclass)}(data, len, out_len);
:: #endif
:: #endfor
    }
:: #endif

:: # Validate fixed-offset lists
:: for m in ofclass.members:
:: if type(m) == OFDataMember and m.oftype.startswith('list') and m.offset is not None:
:: if m.name in field_length_members:
:: continue # TODO handle field length members
:: #endif
:: element_name = m.oftype[8:-3]
:: list_validator_name = raw_validator_name('of_list_' + element_name, version)
    if (${list_validator_name}(data + ${m.offset}, len - ${m.offset}, out_len) < 0) {
        return -1;
    }

:: #endif
:: #endfor

:: # TODO handle non-fixed-offset lists

    *out_len = len;
    return 0;
}

:: #endfor
:: #endfor

int
of_validate_message(of_message_t msg, int len)
{
    of_version_t version;
    if (len < OF_MESSAGE_MIN_LENGTH ||
        len != of_message_length_get(msg)) {
        VALIDATOR_LOG("message length %d != %d", len,
                      of_message_length_get(msg));
        return -1;
    }

    version = of_message_version_get(msg);
    int out_len;
    switch (version) {
:: for version, proto in loxi_globals.ir.items():
    case ${version.constant_version(prefix='OF_VERSION_')}:
        return ${validator_name(proto.class_by_name('of_header'))}(msg, len, &out_len);
:: #endfor
    default:
        VALIDATOR_LOG("Bad version %d", OF_VERSION_1_3);
        return -1;
    }
}
