summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipip/ipip.api
blob: 2740a51aae1825a998e3cec3018b44bee46e1a7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* Hey Emacs use -*- mode: C -*- */
/*
 * 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.
 */

/**
 * The IPIP module implements IP{v4,v6} over IP{v4,v6} tunnelling as
 * described in RFC2473 and to some extent the largely historical
 * RFC1853.  The module also supports an IPv4 over IPv6 automatic
 * tunnelling mechanism called 6RD (RFC5969).
 *
 * The IPIP API module supports a CRD model for adding, deleting and
 * listing tunnels. A tunnel is represented as an interface in
 * VPP. The "handle" representing a tunnel is the sw_if_index.  As any
 * interface, the user must configure an IPv4 and/or IPv6 address on
 * the interface. This is the inner or payload protocol.
 *
 * Tunnel MTU: The tunnel MTU (the payload MTU) is configurable per
 * protocol. If a tunnel MTU is larger than the path MTU, the outer
 * packet will be fragmented. Fragmentation support is configurable,
 * as it can have severe performance issues, and might be used as an
 * attack vector (the remote side must reassemble.)
 *
 * Traffic class / TOS field can either be configured to a fixed
 * value, or can be copied from the inner to the outer header.
 * (For now we have stolen ~0 to indicate copy).
 *
 * Note:
 *
 * - The Tunnel encapsulation limit described in RFC2473 is not
 *   implemented.
 *
 * - ICMP proxying, as in a tunnel head-end receiving ICMP erors on
 *   the outer packet is currently not relayed to the original source
 *   of the packet.
 *
 * - PMTUD / MTU probing and tunnel keepalives are not yet implemented.
 *
 */

option version = "2.0.2";

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

/**
 * An IP{v4,v6} over IP{v4,v6} tunnel.
 */
typedef ipip_tunnel
{
  u32 instance; /* If non-~0, specifies a custom dev instance */
  vl_api_address_t src;
  vl_api_address_t dst;
  vl_api_interface_index_t sw_if_index; /* ignored on create, set in
					   details/dump */
  u32 table_id;
  vl_api_tunnel_encap_decap_flags_t flags;
  vl_api_tunnel_mode_t mode;
  vl_api_ip_dscp_t dscp; /* DSCP value for the tunnel encap,
                            ignored if ECNAP_COPY_DSCP flag is set */
};

/**
 * Create an IP{v4,v6} over IP{v4,v6} tunnel.
 */
define ipip_add_tunnel
{
  u32 client_index;
  u32 context;
  vl_api_ipip_tunnel_t tunnel;
};

define ipip_add_tunnel_reply
{
  u32 context;
  i32 retval;
  vl_api_interface_index_t sw_if_index;
};

/**
 * Delete an IP{v4,v6} over IP{v4,v6} tunnel.
 */
autoreply define ipip_del_tunnel
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};

/**
 * Create an IPv4 over IPv6 automatic tunnel (6RD)
 */
define ipip_6rd_add_tunnel
{
  u32 client_index;
  u32 context;
  u32 ip6_table_id;
  u32 ip4_table_id;
  vl_api_ip6_prefix_t ip6_prefix;
  vl_api_ip4_prefix_t ip4_prefix;
  vl_api_ip4_address_t ip4_src;
  bool security_check;
  u8 tc_tos; /* If ~0, the TOS/TC value is copied from
                inner packet, otherwise set to value */
};

define ipip_6rd_add_tunnel_reply
{
  u32 context;
  i32 retval;
  vl_api_interface_index_t sw_if_index;
};

/**
 * Delete an IPv4 over IPv6 automatic tunnel (6RD)
 */
autoreply define ipip_6rd_del_tunnel
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};

/**
 * List all IPIP tunnels
 */
define ipip_tunnel_dump
{
  u32 client_index;
  u32 context;
  vl_api_interface_index_t sw_if_index;
};

define ipip_tunnel_details
{
  u32 context;
  vl_api_ipip_tunnel_t tunnel;
};
an class="n">ipip_mode_t mode; u16 __pad; } __clib_packed ipip_tunnel_key_t; STATIC_ASSERT_SIZEOF (ipip_tunnel_key_t, 5 * sizeof (u64)); /** * @brief A representation of a IPIP tunnel */ typedef struct { /* Required for pool_get_aligned */ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); ipip_mode_t mode; ipip_transport_t transport; ip46_address_t tunnel_src; ip46_address_t tunnel_dst; u32 fib_index; u32 hw_if_index; u32 sw_if_index; u32 dev_instance; /* Real device instance in tunnel vector */ u32 user_instance; /* Instance name being shown to user */ tunnel_encap_decap_flags_t flags; ip_dscp_t dscp; struct { ip6_address_t ip6_prefix; ip4_address_t ip4_prefix; u8 ip6_prefix_len; u8 ip4_prefix_len; u8 shift; bool security_check; u32 ip6_fib_index; } sixrd; } ipip_tunnel_t; typedef struct { ipip_tunnel_t *tunnels; uword *tunnel_by_key; u32 *tunnel_index_by_sw_if_index; /* convenience */ vlib_main_t *vlib_main; vnet_main_t *vnet_main; /* Record used instances */ uword *instance_used; bool ip4_protocol_registered; bool ip6_protocol_registered; u16 msg_id_base; } ipip_main_t; extern ipip_main_t ipip_main; extern vlib_node_registration_t ipip4_input_node; extern vlib_node_registration_t ipip6_input_node; /* * sixrd_get_addr_net */ static_always_inline u32 sixrd_get_addr_net (const ipip_tunnel_t * t, u64 dal) { /* 1:1 mode */ if (t->sixrd.ip4_prefix_len == 32) return (t->sixrd.ip4_prefix.as_u32); dal = clib_net_to_host_u64 (dal); /* Grab 32 - ip4_prefix_len bits out of IPv6 address from offset * ip6_prefix_len */ u32 mask = ~(~0ULL << (32 - t->sixrd.ip4_prefix_len)); u32 ip4 = clib_net_to_host_u32 (t->sixrd. ip4_prefix.as_u32) | ((u32) (dal >> t->sixrd. shift) & mask); return clib_host_to_net_u32 (ip4); } int ipip_add_tunnel (ipip_transport_t transport, u32 instance, ip46_address_t * src, ip46_address_t * dst, u32 fib_index, tunnel_encap_decap_flags_t flags, ip_dscp_t dscp, tunnel_mode_t mode, u32 * sw_if_indexp); int ipip_del_tunnel (u32 sw_if_index); int sixrd_add_tunnel (ip6_address_t * ip6_prefix, u8 ip6_prefix_len, ip4_address_t * ip4_prefix, u8 ip4_prefix_len, ip4_address_t * ip4_src, bool security_check, u32 ip4_fib_index, u32 ip6_fib_index, u32 * sw_if_index); int sixrd_del_tunnel (u32 sw_if_index); void ipip_tunnel_db_add (ipip_tunnel_t * t, const ipip_tunnel_key_t * key); void ipip_tunnel_db_remove (ipip_tunnel_t * t, const ipip_tunnel_key_t * key); ipip_tunnel_t *ipip_tunnel_db_find (const ipip_tunnel_key_t * key); ipip_tunnel_t *ipip_tunnel_db_find_by_sw_if_index (u32 sw_if_index); void ipip_mk_key (const ipip_tunnel_t * t, ipip_tunnel_key_t * key); void ipip_mk_key_i (ipip_transport_t transport, ipip_mode_t mode, const ip46_address_t * src, const ip46_address_t * dst, u32 fib_index, ipip_tunnel_key_t * key); #endif /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */