/* * Copyright (c) 2015 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. */ /* * ip6/packet.h: ip6 packet format * * Copyright (c) 2008 Eliot Dresselhaus * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef included_ip6_packet_h #define included_ip6_packet_h #include #include typedef union { u8 as_u8[16]; u16 as_u16[8]; u32 as_u32[4]; u64 as_u64[2]; u64x2 as_u128; uword as_uword[16 / sizeof (uword)]; } __clib_packed ip6_address_t; STATIC_ASSERT_SIZEOF (ip6_address_t, 16); typedef struct { ip6_address_t addr, mask; } ip6_address_and_mask_t; /* Packed so that the mhash key doesn't include uninitialized pad bytes */ /* *INDENT-OFF* */ typedef CLIB_PACKED (struct { /* IP address must be first for ip_interface_address_get_address() to work */ ip6_address_t ip6_addr; u32 fib_index; }) ip6_address_fib_t; /* *INDENT-ON* */ always_inline void ip6_addr_fib_init (ip6_address_fib_t * addr_fib, const ip6_address_t * address, u32 fib_index) { addr_fib->ip6_addr = *address; addr_fib->fib_index = fib_index; } /* Special addresses: unspecified ::/128 loopback ::1/128 global unicast 2000::/3 unique local unicast fc00::/7 link local unicast fe80::/10 multicast ff00::/8 ietf reserved everything else. */ #define foreach_ip6_multicast_address_scope \ _ (loopback, 0x1) \ _ (link_local, 0x2) \ _ (admin_local, 0x4) \ _ (site_local, 0x5) \ _ (organization_local, 0x8) \ _ (global, 0xe) #define foreach_ip6_multicast_link_local_group_id \ _ (all_hosts, 0x1) \ _ (all_routers, 0x2) \ _ (rip_routers, 0x9) \ _ (eigrp_routers, 0xa) \ _ (pim_routers, 0xd) \ _ (mldv2_routers, 0x16) typedef enum { #define _(f,n) IP6_MULTICAST_SCOPE_##f = n, foreach_ip6_multicast_address_scope #undef _ } ip6_multicast_address_scope_t; typedef enum { #define _(f,n) IP6_MULTICAST_GROUP_ID_##f = n, foreach_ip6_multicast_link_local_group_id #undef _ } ip6_multicast_link_local_group_id_t; always_inline uword ip6_address_is_multicast (const ip6_address_t * a) { return a->as_u8[0] == 0xff; } always_inline void ip6_address_copy (ip6_address_t * dst, const ip6_address_t * src) { dst->as_u64[0] = src->as_u64[0]; dst->as_u64[1] = src->as_u64[1]; } always_inline void ip6_set_reserved_multicast_address (ip6_address_t * a, ip6_multicast_address_scope_t scope, u16 id) { a->as_u64[0] = a->as_u64[1] = 0; a->as_u16[0] = clib_host_to_net_u16 (0xff00 | scope); a->as_u16[7] = clib_host_to_net_u16 (id); } always_inline void ip6_set_solicited_node_multicast_address (ip6_address_t * a, u32 id) { /* 0xff02::1:ffXX:XXXX. */ a->as_u64[0] = a->as_u64[1] = 0; a->as_u16[0] = clib_host_to_net_u16 (0xff02); a->as_u8[11] = 1; ASSERT ((id >> 24) == 0); id |= 0xff << 24; a->as_u32[3] = clib_host_to_net_u32 (id); } always_inline void ip6_multicast_ethernet_address (u8 * ethernet_address, u32 group_id) { ethernet_address[0] = 0x33; ethernet_address[1] = 0x33; ethernet_address[2] = ((group_id >> 24) & 0xff); ethernet_address[3] = ((group_id >> 16) & 0xff); ethernet_address[4] = ((group_id >> 8) & 0xff); ethernet_address[5] = ((group_id >> 0) & 0xff); } always_inline uword ip6_address_is_equal (const ip6_address_t * a, const ip6_address_t * b) { int i; for (i = 0; i < ARRAY_LEN (a->as_uword); i++) if (a->as_uword[i] != b->as_uword[i]) return 0; return 1; } always_inline uword ip6_address_is_equal_masked (const ip6_address_t * a, const ip6_address_t * b, const ip6_address_t * mask) { int i; for (i = 0; i < ARRAY_LEN (a->as_uword); i++) { uword a_masked, b_masked; a_masked = a->as_uword[i] & mask->as_uword[i]; b_masked = b->as_uword[i] & mask->as_uword[i]; if (a_masked != b_masked) return 0; } return 1; } always_inline void ip6_address_mask (ip6_address_t * a, const ip6_address_t * mask) { int i; for (i = 0; i < ARRAY_LEN (a->as_uword); i++) a->as_uword[i] &= mask->as_uword[i]; } always_inline void ip6_address_set_zero (ip6_address_t * a) { int i; for (i = 0; i < ARRAY_LEN (a->as_uword); i++) a->as_uword[i] = 0; } always_inline void ip6_address_mask_from_width (ip6_address_t * a, u32 width) { int i, byte, bit, bitnum; ASSERT (width <= 128); clib_memset (a, 0, sizeof (a[0])); for (i = 0; i < width; i++) { bitnum = (7 - (i & 7)); byte = i / 8; bit = 1 << bitnum; a->as_u8[byte] |= bit; } } always_inline uword ip6_address_is_zero (const ip6_address_t * a) { int i; for (i = 0; i < ARRAY_LEN (a->as_uword); i++) if (a->as_uword[i] != 0) return 0; return 1; } /* Check for unspecified address ::0 */ always_inline uword ip6_address_is_unspecified (const ip6_address_t * a) { return ip6_address_is_zero (a); } /* Check for loopback address ::1 */ always_inline uword ip6_address_is_loopback (const ip6_address_t * a) { return (a->as_u64[0] == 0 && a->as_u32[2] == 0 && a->as_u16[6] == 0 && a->as_u8[14] == 0 && a->as_u8[15] == 1); } /* Check for link local unicast fe80::/10. */ always_inline uword ip6_address_is_link_local_unicast (const ip6_address_t * a) { return a->as_u8[0] ==
/*
 * Copyright (c) 2018 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.
 */

option version = "2.0.0";

import "vnet/interface_types.api";
import "vnet/ip/ip_types.api";

/** \brief Enable/disable DHCPv6 PD client on interface
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @param sw_if_index - interface to enable/disable client on
    @param prefix_group - name of prefix group (relevant when 'enable' is 1)
    @param enable - 1 to enable, 0 to disable
*/
autoreply define dhcp6_pd_client_enable_disable
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
  string prefix_group[64];
  bool enable;
};

/** \brief Add/delete IPv6 address optionally using available prefix
    @param client_index - opaque cookie to identify the sender
    @param context - sender context, to match reply w/ request
    @p