/* * mpls.c: mpls * * Copyright (c) 2012 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. */ #include #include #include #include const static char* mpls_eos_bit_names[] = MPLS_EOS_BITS; mpls_main_t mpls_main; u8 * format_mpls_unicast_label (u8 * s, va_list * args) { mpls_label_t label = va_arg (*args, mpls_label_t); switch (label) { case MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL: s = format (s, "%s", MPLS_IETF_IPV4_EXPLICIT_NULL_STRING); break; case MPLS_IETF_ROUTER_ALERT_LABEL: s = format (s, "%s", MPLS_IETF_ROUTER_ALERT_STRING); break; case MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL: s = format (s, "%s", MPLS_IETF_IPV6_EXPLICIT_NULL_STRING); break; case MPLS_IETF_IMPLICIT_NULL_LABEL: s = format (s, "%s", MPLS_IETF_IMPLICIT_NULL_STRING); break; case MPLS_IETF_ELI_LABEL: s = format (s, "%s", MPLS_IETF_ELI_STRING); break; case MPLS_IETF_GAL_LABEL: s = format (s, "%s", MPLS_IETF_GAL_STRING); break; case MPLS_LABEL_POP: s = format (s, "pop"); break; default: s = format (s, "%d", label); break; } return s; } uword unformat_mpls_unicast_label (unformat_input_t * input, va_list * args) { mpls_label_t *label = va_arg (*args, mpls_label_t*); if (unformat (input, MPLS_IETF_IPV4_EXPLICIT_NULL_STRING)) *label = MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL; else if (unformat (input, MPLS_IETF_IPV6_EXPLICIT_NULL_STRING)) *label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL; else if (unformat (input, MPLS_IETF_ROUTER_ALERT_STRING)) *label = MPLS_IETF_ROUTER_ALERT_LABEL; else if (unformat (input, MPLS_IETF_IMPLICIT_NULL_STRING)) *label = MPLS_IETF_IMPLICIT_NULL_LABEL; else if (unformat (input, MPLS_IETF_IPV4_EXPLICIT_NULL_BRIEF_STRING)) *label = MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL; else if (unformat (input, MPLS_IETF_IPV6_EXPLICIT_NULL_BRIEF_STRING)) *label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL; else if (unformat (input, MPLS_IETF_ROUTER_ALERT_BRIEF_STRING)) *label = MPLS_IETF_ROUTER_ALERT_LABEL; else if (unformat (input, MPLS_IETF_IMPLICIT_NULL_BRIEF_STRING)) *label = MPLS_IETF_IMPLICIT_NULL_LABEL; else if (unformat (input, "%d", label)) ; else return (0); return (1); } u8 * format_mpls_eos_bit (u8 * s, va_list * args) { mpls_eos_bit_t eb = va_arg (*args, mpls_eos_bit_t); ASSERT(eb <= MPLS_EOS); s = format(s, "%s", mpls_eos_bit_names[eb]); return (s); } u8 * format_mpls_header (u8 * s, va_list * args) { mpls_unicast_header_t hdr = va_arg (*args, mpls_unicast_header_t); return (format(s, "[%U:%d:%d:%U]", format_mpls_unicast_label, vnet_mpls_uc_get_label(hdr.label_exp_s_ttl), vnet_mpls_uc_get_ttl(hdr.label_exp_s_ttl), vnet_mpls_uc_get_exp(hdr.label_exp_s_ttl), format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr.label_exp_s_ttl))); } uword unformat_mpls_header (unformat_input_t * input, va_list * args) { u8 ** result = va_arg (*args, u8 **); mpls_unicast_header_t _h, * h = &_h; u32 label, label_exp_s_ttl; if (! unformat (input, "MPLS %d", &label)) return 0; label_exp_s_ttl = (label<<12) | (1<<8) /* s-bit */ | 0xFF; h->label_exp_s_ttl = clib_host_to_net_u32 (label_exp_s_ttl); /* Add gre, mpls headers to result. */ { void * p; u32 h_n_bytes = sizeof (h[0]); vec_add2 (*result, p, h_n_bytes); clib_memcpy (p, h, h_n_bytes); } return 1; } uword unformat_mpls_label_net_byte_order (unformat_input_t * input, va_list * args) { u32 * result = va_arg (*args, u32 *); u32 label; if (!unformat (input, "MPLS: label %d", &label)) return 0; label = (label<<12) | (1<<8) /* s-bit set */ | 0xFF /* ttl */; *result = clib_host_to_net_u32 (label); return 1; } u8 * format_mpls_unicast_header_host_byte_order (u8 * s, va_list * args) { mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *); u32 label = h->label_exp_s_ttl; s = format (s, "label %d exp %d, s %d, ttl %d", vnet_mpls_uc_get_label (label), vnet_mpls_uc_get_exp (label), vnet_mpls_uc_get_s (label), vnet_mpls_uc_get_ttl (label)); return s; } u8 * format_mpls_unicast_header_net_byte_order (u8 * s, va_list * args) { mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *); mpls_unicast_header_t h_host; h_host.label_exp_s_ttl = clib_net_to_host_u32 (h->label_exp_s_ttl); return format (s, "%U", format_mpls_unicast_header_host_byte_order,