FD.io VPP  v16.09
Vector Packet Processing
ppp.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  * ppp.c: ppp support
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/ppp/ppp.h>
42 
43 /* Global main structure. */
45 
46 u8 * format_ppp_protocol (u8 * s, va_list * args)
47 {
48  ppp_protocol_t p = va_arg (*args, u32);
49  ppp_main_t * pm = &ppp_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_ppp_header_with_length (u8 * s, va_list * args)
61 {
62  ppp_main_t * pm = &ppp_main;
63  ppp_header_t * h = va_arg (*args, ppp_header_t *);
64  u32 max_header_bytes = va_arg (*args, u32);
65  ppp_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, "ppp header truncated");
71 
72  indent = format_get_indent (s);
73 
74  s = format (s, "PPP %U", format_ppp_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_ppp_header (u8 * s, va_list * args)
96 {
97  ppp_header_t * h = va_arg (*args, ppp_header_t *);
98  return format (s, "%U", format_ppp_header_with_length, h, 0);
99 }
100 
101 /* Returns ppp protocol as an int in host byte order. */
102 uword
104  va_list * args)
105 {
106  u16 * result = va_arg (*args, u16 *);
107  ppp_main_t * pm = &ppp_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_ppp_header (unformat_input_t * input, va_list * args)
145 {
146  u8 ** result = va_arg (*args, u8 **);
147  ppp_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 
171  u32 sw_if_index,
172  u32 l3_type,
173  void * dst_address,
174  void * rewrite,
175  uword max_rewrite_bytes)
176 {
177  ppp_header_t * h = rewrite;
178  ppp_protocol_t protocol;
179 
180  if (max_rewrite_bytes < sizeof (h[0]))
181  return 0;
182 
183  switch (l3_type) {
184 #define _(a,b) case VNET_L3_PACKET_TYPE_##a: protocol = PPP_PROTOCOL_##b; break
185  _ (IP4, ip4);
186  _ (IP6, ip6);
187  _ (MPLS_UNICAST, mpls_unicast);
188  _ (MPLS_MULTICAST, mpls_multicast);
189 #undef _
190  default:
191  return 0;
192  }
193 
194  h->address = 0xff;
195  h->control = 0x03;
196  h->protocol = clib_host_to_net_u16 (protocol);
197 
198  return sizeof (h[0]);
199 }
200 
202  .name = "PPP",
203  .format_header = format_ppp_header_with_length,
204  .unformat_header = unformat_ppp_header,
205  .set_rewrite = ppp_set_rewrite,
206 };
207 
208 static void add_protocol (ppp_main_t * pm,
209  ppp_protocol_t protocol,
210  char * protocol_name)
211 {
212  ppp_protocol_info_t * pi;
213  u32 i;
214 
215  vec_add2 (pm->protocol_infos, pi, 1);
216  i = pi - pm->protocol_infos;
217 
218  pi->name = protocol_name;
219  pi->protocol = protocol;
220  pi->next_index = pi->node_index = ~0;
221 
222  hash_set (pm->protocol_info_by_protocol, protocol, i);
224 }
225 
227 {
228  ppp_main_t * pm = &ppp_main;
229 
230  memset (pm, 0, sizeof (pm[0]));
231  pm->vlib_main = vm;
232 
233  pm->protocol_info_by_name = hash_create_string (0, sizeof (uword));
234  pm->protocol_info_by_protocol = hash_create (0, sizeof (uword));
235 
236 #define _(n,s) add_protocol (pm, PPP_PROTOCOL_##s, #s);
238 #undef _
239 
241 }
242 
244 
246 {
248  return &ppp_main;
249 }
250 
#define hash_set(h, key, value)
Definition: hash.h:254
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
u16 protocol
Definition: packet.h:186
static void add_protocol(ppp_main_t *pm, ppp_protocol_t protocol, char *protocol_name)
Definition: ppp.c:208
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:521
#define hash_set_mem(h, key, value)
Definition: hash.h:274
uword * protocol_info_by_protocol
Definition: ppp.h:76
u32 next_index
Definition: ppp.h:67
u8 address
Definition: packet.h:183
ppp_protocol_t
Definition: packet.h:150
ppp_main_t * ppp_get_main(vlib_main_t *vm)
Definition: ppp.c:245
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
u8 * format_ppp_header_with_length(u8 *s, va_list *args)
Definition: ppp.c:60
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.
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
#define vlib_call_init_function(vm, x)
Definition: init.h:161
#define hash_create_string(elts, value_bytes)
Definition: hash.h:641
static uword format_get_indent(u8 *s)
Definition: format.h:72
ppp_main_t ppp_main
Definition: ppp.c:44
VNET_HW_INTERFACE_CLASS(ppp_hw_interface_class)
format_function_t * format_buffer
Definition: node.h:311
u32 node_index
Definition: ppp.h:64
u8 control
Definition: packet.h:183
static ppp_protocol_info_t * ppp_get_protocol_info(ppp_main_t *em, ppp_protocol_t protocol)
Definition: ppp.h:80
ppp_protocol_info_t * protocol_infos
Definition: ppp.h:73
#define clib_memcpy(a, b, c)
Definition: string.h:63
uword unformat_vlib_number_by_name(unformat_input_t *input, va_list *args)
Definition: format.c:157
u8 * format_ppp_header(u8 *s, va_list *args)
Definition: ppp.c:95
uword * protocol_info_by_name
Definition: ppp.h:76
Definition: ppp.h:70
#define hash_create(elts, value_bytes)
Definition: hash.h:647
unsigned int u32
Definition: types.h:88
vlib_main_t * vlib_main
Definition: ppp.h:71
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:418
static uword ppp_set_rewrite(vnet_main_t *vnm, u32 sw_if_index, u32 l3_type, void *dst_address, void *rewrite, uword max_rewrite_bytes)
Definition: ppp.c:170
ppp_protocol_t protocol
Definition: ppp.h:61
char * name
Definition: ppp.h:58
u64 uword
Definition: types.h:112
uword unformat_ppp_protocol_host_byte_order(unformat_input_t *input, va_list *args)
Definition: ppp.c:103
unsigned short u16
Definition: types.h:57
unsigned char u8
Definition: types.h:56
Definition: lisp_types.h:24
static clib_error_t * ppp_init(vlib_main_t *vm)
Definition: ppp.c:226
uword unformat_ppp_header(unformat_input_t *input, va_list *args)
Definition: ppp.c:144
static clib_error_t * ppp_input_init(vlib_main_t *vm)
Definition: node.c:274
u8 * format_ppp_protocol(u8 *s, va_list *args)
Definition: ppp.c:46
vnet_hw_interface_class_t ppp_hw_interface_class
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:58
struct _unformat_input_t unformat_input_t
Definition: lisp_types.h:25
uword unformat_ppp_protocol_net_byte_order(unformat_input_t *input, va_list *args)
Definition: ppp.c:133