FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
hdlc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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  */
15 /*
16  * hdlc.c: hdlc
17  *
18  * Copyright (c) 2010 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vnet/vnet.h>
41 #include <vnet/hdlc/hdlc.h>
42 
43 /* Global main structure. */
45 
46 u8 * format_hdlc_protocol (u8 * s, va_list * args)
47 {
48  hdlc_protocol_t p = va_arg (*args, u32);
49  hdlc_main_t * pm = &hdlc_main;
51 
52  if (pi)
53  s = format (s, "%s", pi->name);
54  else
55  s = format (s, "0x%04x", p);
56 
57  return s;
58 }
59 
60 u8 * format_hdlc_header_with_length (u8 * s, va_list * args)
61 {
62  hdlc_main_t * pm = &hdlc_main;
63  hdlc_header_t * h = va_arg (*args, hdlc_header_t *);
64  u32 max_header_bytes = va_arg (*args, u32);
65  hdlc_protocol_t p = clib_net_to_host_u16 (h->protocol);
66  uword indent, header_bytes;
67 
68  header_bytes = sizeof (h[0]);
69  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
70  return format (s, "hdlc header truncated");
71 
72  indent = format_get_indent (s);
73 
74  s = format (s, "HDLC %U", format_hdlc_protocol, p);
75 
76  if (h->address != 0xff)
77  s = format (s, ", address 0x%02x", h->address);
78  if (h->control != 0x03)
79  s = format (s, ", control 0x%02x", h->control);
80 
81  if (max_header_bytes != 0 && header_bytes > max_header_bytes)
82  {
84  vlib_node_t * node = vlib_get_node (pm->vlib_main, pi->node_index);
85  if (node->format_buffer)
86  s = format (s, "\n%U%U",
87  format_white_space, indent,
88  node->format_buffer, (void *) (h + 1),
89  max_header_bytes - header_bytes);
90  }
91 
92  return s;
93 }
94 
95 u8 * format_hdlc_header (u8 * s, va_list * args)
96 {
97  hdlc_header_t * h = va_arg (*args, hdlc_header_t *);
98  return format (s, "%U", format_hdlc_header_with_length, h, 0);
99 }
100 
101 /* Returns hdlc protocol as an int in host byte order. */
102 uword
104  va_list * args)
105 {
106  u16 * result = va_arg (*args, u16 *);
107  hdlc_main_t * pm = &hdlc_main;
108  int p, i;
109 
110  /* Numeric type. */
111  if (unformat (input, "0x%x", &p)
112  || unformat (input, "%d", &p))
113  {
114  if (p >= (1 << 16))
115  return 0;
116  *result = p;
117  return 1;
118  }
119 
120  /* Named type. */
122  pm->protocol_info_by_name, &i))
123  {
125  *result = pi->protocol;
126  return 1;
127  }
128 
129  return 0;
130 }
131 
132 uword
134  va_list * args)
135 {
136  u16 * result = va_arg (*args, u16 *);
138  return 0;
139  *result = clib_host_to_net_u16 ((u16) *result);
140  return 1;
141 }
142 
143 uword
144 unformat_hdlc_header (unformat_input_t * input, va_list * args)
145 {
146  u8 ** result = va_arg (*args, u8 **);
147  hdlc_header_t _h, * h = &_h;
148  u16 p;
149 
150  if (! unformat (input, "%U",
152  return 0;
153 
154  h->address = 0xff;
155  h->control = 0x03;
156  h->protocol = clib_host_to_net_u16 (p);
157 
158  /* Add header to result. */
159  {
160  void * p;
161  u32 n_bytes = sizeof (h[0]);
162 
163  vec_add2 (*result, p, n_bytes);
164  clib_memcpy (p, h, n_bytes);
165  }
166 
167  return 1;
168 }
169 
170 static u8*
172  u32 sw_if_index,
173  vnet_link_t link_type,
174  const void *dst_address)
175 {
176  hdlc_header_t * h;
177  u8* rewrite = NULL;
178  hdlc_protocol_t protocol;
179 
180  switch (link_type) {
181 #define _(a,b) case VNET_LINK_##a: protocol = HDLC_PROTOCOL_##b; break
182  _ (IP4, ip4);
183  _ (IP6, ip6);
184  _ (MPLS, mpls_unicast);
185 #undef _
186  default:
187  return (NULL);
188  }
189 
190  vec_validate(rewrite, sizeof(*h)-1);
191  h = (hdlc_header_t *)rewrite;
192  h->address = 0x0f;
193  h->control = 0x00;
194  h->protocol = clib_host_to_net_u16 (protocol);
195 
196  return (rewrite);
197 }
198 
200  .name = "HDLC",
201  .format_header = format_hdlc_header_with_length,
202  .unformat_header = unformat_hdlc_header,
203  .build_rewrite = hdlc_build_rewrite,
205 };
206 
207 static void add_protocol (hdlc_main_t * pm,
208  hdlc_protocol_t protocol,
209  char * protocol_name)
210 {
212  u32 i;
213 
214  vec_add2 (pm->protocol_infos, pi, 1);
215  i = pi - pm->protocol_infos;
216 
217  pi->name = protocol_name;
218  pi->protocol = protocol;
219  pi->next_index = pi->node_index = ~0;
220 
221  hash_set (pm->protocol_info_by_protocol, protocol, i);
223 }
224 
226 {
227  hdlc_main_t * pm = &hdlc_main;
228 
229  memset (pm, 0, sizeof (pm[0]));
230  pm->vlib_main = vm;
231 
232  pm->protocol_info_by_name = hash_create_string (0, sizeof (uword));
233  pm->protocol_info_by_protocol = hash_create (0, sizeof (uword));
234 
235 #define _(n,s) add_protocol (pm, HDLC_PROTOCOL_##s, #s);
237 #undef _
238 
240 }
241 
243 
245 {
247  return &hdlc_main;
248 }
249 
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
vnet_hw_interface_class_t hdlc_hw_interface_class
#define hash_set(h, key, value)
Definition: hash.h:254
static hdlc_protocol_info_t * hdlc_get_protocol_info(hdlc_main_t *em, hdlc_protocol_t protocol)
Definition: hdlc.h:80
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
u8 * format_hdlc_protocol(u8 *s, va_list *args)
Definition: hdlc.c:46
u8 control
Definition: packet.h:63
#define NULL
Definition: clib.h:55
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:561
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:982
#define hash_set_mem(h, key, value)
Definition: hash.h:274
static clib_error_t * hdlc_input_init(vlib_main_t *vm)
Definition: node.c:307
u8 * format_hdlc_header(u8 *s, va_list *args)
Definition: hdlc.c:95
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
uword unformat_hdlc_protocol_net_byte_order(unformat_input_t *input, va_list *args)
Definition: hdlc.c:133
hdlc_protocol_t
Definition: packet.h:52
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static uword format_get_indent(u8 *s)
Definition: format.h:72
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static clib_error_t * hdlc_init(vlib_main_t *vm)
Definition: hdlc.c:225
hdlc_main_t hdlc_main
Definition: hdlc.c:44
#define vlib_call_init_function(vm, x)
Definition: init.h:162
#define hash_create_string(elts, value_bytes)
Definition: hash.h:652
struct _unformat_input_t unformat_input_t
uword unformat_hdlc_header(unformat_input_t *input, va_list *args)
Definition: hdlc.c:144
format_function_t * format_buffer
Definition: node.h:311
uword * protocol_info_by_protocol
Definition: hdlc.h:76
u8 * format_hdlc_header_with_length(u8 *s, va_list *args)
Definition: hdlc.c:60
vlib_main_t * vm
Definition: buffer.c:276
vec_header_t h
Definition: buffer.c:275
vlib_main_t * vlib_main
Definition: hdlc.h:71
#define clib_memcpy(a, b, c)
Definition: string.h:69
#define hash_create(elts, value_bytes)
Definition: hash.h:658
hdlc_main_t * hdlc_get_main(vlib_main_t *vm)
Definition: hdlc.c:244
unsigned int u32
Definition: types.h:88
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
uword unformat_vlib_number_by_name(unformat_input_t *input, va_list *args)
Definition: format.c:157
u8 address
Definition: packet.h:60
uword * protocol_info_by_name
Definition: hdlc.h:76
VNET_HW_INTERFACE_CLASS(hdlc_hw_interface_class)
u64 uword
Definition: types.h:112
unsigned short u16
Definition: types.h:57
unsigned char u8
Definition: types.h:56
static void add_protocol(hdlc_main_t *pm, hdlc_protocol_t protocol, char *protocol_name)
Definition: hdlc.c:207
a point 2 point interface
Definition: interface.h:274
Definition: lisp_types.h:37
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:58
hdlc_protocol_info_t * protocol_infos
Definition: hdlc.h:73
hdlc_protocol_t protocol
Definition: hdlc.h:61
uword unformat_hdlc_protocol_host_byte_order(unformat_input_t *input, va_list *args)
Definition: hdlc.c:103
Definition: lisp_types.h:38
static u8 * hdlc_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
Definition: hdlc.c:171
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
u16 protocol
Definition: packet.h:66