/* * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 License for the specific language governing permissions and * limitations under the License. */ #ifndef __HICN_PARSER_H__ #define __HICN_PARSER_H__ #include #include "hicn.h" #include "error.h" #include "infra.h" /** * @file parser.h */ #define PARSE(PACKET_TYPE) \ do \ { \ if (pkt == NULL) \ return HICN_ERROR_PARSER_PKT_INVAL; \ \ int ret = HICN_LIB_ERROR_NONE; \ \ hicn_header_t *pkt_hdr; \ u8 *ip_pkt; \ u8 ip_proto; \ int isv6; \ u8 next_proto_offset; \ hicn_type_t type; \ hicn_name_t *name; \ u16 *port; \ hicn_lifetime_t *lifetime; \ \ /* start parsing first fields to get the protocols */ \ pkt_hdr = vlib_buffer_get_current (pkt); \ isv6 = hicn_is_v6 (pkt_hdr); \ \ ip_pkt = vlib_buffer_get_current (pkt); \ ip_proto = (1 - isv6) * IPPROTO_IP + (isv6) *IPPROTO_IPV6; \ \ /* in the ipv6 header the next header field is at byte 6 in the ipv4*/ \ /* header the protocol field is at byte 9*/ \ next_proto_offset = 6 + (1 - isv6) * 3; \ \ /* get type info*/ \ type.l4 = IPPROTO_NONE; \ type.l3 = ip_pkt[next_proto_offset] == IPPROTO_UDP ? IPPROTO_ENCAP : \ IPPROTO_NONE; \ type.l2 = ip_pkt[next_proto_offset]; \ type.l1 = ip_proto; \ \ /* cache hicn packet type in opaque2*/ \ hicn_get_buffer (pkt)->type = type; \ \ /* get name and name length*/ \ name = &hicn_get_buffer (pkt)->name; \ ret = hicn_ops_vft[type.l1]->get_##PACKET_TYPE##_name ( \ type, &pkt_hdr->protocol, name); \ if (PREDICT_FALSE (ret)) \ { \ if (type.l2 == IPPROTO_ICMPV4 || type.l2 == IPPROTO_ICMPV6) \ { \ return HICN_ERROR_PARSER_MAPME_PACKET; \ } \ return HICN_ERROR_PARSER_PKT_INVAL; \ } \ \ /* get source port*/ \ port = &hicn_get_buffer (pkt)->port; \ hicn_ops_vft[type.l1]->get_source_port (type, &pkt_hdr->protocol, \ port); \ if (PREDICT_FALSE (ret)) \ { \ return HICN_ERROR_PARSER_PKT_INVAL; \ } \ \ /* get lifetime*/ \ lifetime = &hicn_get_buffer (pkt)->lifetime; \ hicn_ops_vft[type.l1]->get_lifetime (type, &pkt_hdr->protocol, \ lifetime); \ \ if (*lifetime > hicn_main.pit_lifetime_max_ms) \ *lifetime = hicn_main.pit_lifetime_max_ms; \ \ return ret; \ } \ while (0) /** * @brief Parse a interest packet * * @param pkt vlib buffer holding the interest * @param name [RETURNED] variable that will point to the hicn name * @param namelen [RETURNED] variable that will hold the length of the name * @param port [RETURNED] variable that will hold the source port of the packet * @param pkt_hdrp [RETURNED] valiable that will point to the packet header * @param isv6 [RETURNED] variable that will be equale to 1 is the header is * ipv6 */ always_inline int hicn_interest_parse_pkt (vlib_buffer_t *pkt) { PARSE (interest); } /** * @brief Parse a data packet * * @param pkt vlib buffer holding the data * @param name [RETURNED] variable that will point to the hicn name * @param namelen [RETURNED] variable that will hold the length of the name * @param port [RETURNED] variable that will hold the source port of the packet * @param pkt_hdrp [RETURNED] valiable that will point to the packet header * @param isv6 [RETURNED] variable that will be equale to 1 is the header is * ipv6 */ always_inline int hicn_data_parse_pkt (vlib_buffer_t *pkt) { PARSE (data); } #endif /* __HICN_PARSER_H__ */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: eval: (c-set-style "gnu") End: */