1 /*---------------------------------------------------------------------------
2 * Copyright (c) 2009-2014 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *---------------------------------------------------------------------------
17 #include <vppinfra/error.h>
18 #include <vnet/vnet.h>
19 #include <vnet/ip/ip.h>
21 int sixrd_create_domain(ip6_address_t *ip6_prefix, u8 ip6_prefix_len,
22 ip4_address_t *ip4_prefix, u8 ip4_prefix_len,
23 ip4_address_t *ip4_src, u32 *sixrd_domain_index, u16 mtu);
24 int sixrd_delete_domain(u32 sixrd_domain_index);
25 u8 *format_sixrd_trace(u8 *s, va_list *args);
28 ip6_address_t ip6_prefix;
29 ip4_address_t ip4_prefix;
30 ip4_address_t ip4_src;
41 /* pool of SIXRD domains */
42 sixrd_domain_t *domains;
45 vlib_main_t *vlib_main;
46 vnet_main_t *vnet_main;
48 u32 ip4_lookup_next_index;
49 u32 ip6_lookup_next_index;
52 #define foreach_sixrd_error \
53 /* Must be first. */ \
54 _(NONE, "valid SIXRD packets") \
55 _(BAD_PROTOCOL, "bad protocol") \
56 _(WRONG_ICMP_TYPE, "wrong icmp type") \
57 _(SEC_CHECK, "security check failed") \
58 _(ICMP, "unable to translate ICMP") \
59 _(UNKNOWN, "unknown") \
60 _(NO_DOMAIN, "no domain") \
61 _(ENCAPSULATED, "encapsulated") \
62 _(DECAPSULATED, "decapsulated") \
63 _(TRANSLATED_4TO6, "translated 4 to 6") \
64 _(TRANSLATED_6TO4, "translated 6 to 4") \
65 _(FRAGMENT, "fragment handling error") \
66 _(FRAGMENT_QUEUED, "dropped, missing first fragment") \
67 _(FRAGMENTED, "packets requiring fragmentation") \
68 _(FRAGMENT_PARTS, "fragment parts") \
69 _(MALFORMED, "malformed packet")
72 #define _(sym,str) SIXRD_ERROR_##sym,
79 u32 sixrd_domain_index;
82 sixrd_main_t sixrd_main;
87 static_always_inline u32
88 sixrd_get_addr (sixrd_domain_t *d, u64 dal)
92 if (d->ip4_prefix_len == 32) return (d->ip4_prefix.as_u32);
94 /* Grab 32 - ip4_prefix_len bits out of IPv6 address from offset ip6_prefix_len */
95 return (d->ip4_prefix.as_u32 | (u32)(dal >> d->shift));
99 * Get the SIXRD domain from an IPv6 lookup adjacency.
101 static_always_inline sixrd_domain_t *
102 ip6_sixrd_get_domain (u32 adj_index, u32 *sixrd_domain_index)
104 sixrd_main_t *mm = &sixrd_main;
105 ip_lookup_main_t *lm = &ip6_main.lookup_main;
106 ip_adjacency_t *adj = ip_get_adjacency(lm, adj_index);
108 uword *p = (uword *)adj->rewrite_data;
110 *sixrd_domain_index = p[0];
111 return pool_elt_at_index(mm->domains, p[0]);
115 * Get the SIXRD domain from an IPv4 lookup adjacency.
116 * If the IPv4 address is not shared, no lookup is required.
117 * The IPv6 address is used otherwise.
119 static_always_inline sixrd_domain_t *
120 ip4_sixrd_get_domain (u32 adj_index, ip6_address_t *addr,
121 u32 *sixrd_domain_index, u8 *error)
123 sixrd_main_t *mm = &sixrd_main;
124 ip6_main_t *im6 = &ip6_main;
125 ip_lookup_main_t *lm4 = &ip4_main.lookup_main;
126 ip_lookup_main_t *lm6 = &ip6_main.lookup_main;
127 ip_adjacency_t *adj = ip_get_adjacency(lm4, adj_index);
129 uword *p = (uword *)adj->rewrite_data;
131 *sixrd_domain_index = p[0];
133 return pool_elt_at_index(mm->domains, p[0]);
135 u32 ai = ip6_fib_lookup_with_table(im6, 0, addr);
136 ip_adjacency_t *adj6 = ip_get_adjacency (lm6, ai);
137 if (PREDICT_TRUE(adj6->lookup_next_index == IP_LOOKUP_NEXT_SIXRD)) {
138 uword *p = (uword *)adj6->rewrite_data;
139 *sixrd_domain_index = p[0];
140 return pool_elt_at_index(mm->domains, *sixrd_domain_index);
142 *error = SIXRD_ERROR_NO_DOMAIN;