Initial commit of vpp code.
[vpp.git] / vnet / vnet / mcast / mcast_test.c
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 #include <vnet/mcast/mcast.h>
16
17 #include <vlib/vlib.h>
18 #include <vnet/vnet.h>
19 #include <vnet/pg/pg.h>
20 #include <vppinfra/error.h>
21 #include <vnet/ip/lookup.h>
22 #include <vnet/ip/ip4_packet.h>
23 #include <vnet/ip/icmp46_packet.h>
24 #include <vnet/ip/ip4.h>
25 #include <vnet/mcast/mcast.h>
26
27 typedef struct {
28   /* convenience */
29   vlib_main_t * vlib_main;
30   vnet_main_t * vnet_main;
31   mcast_main_t * mcast_main;
32 } mcast_test_main_t;
33
34 mcast_test_main_t mcast_test_main;
35 vlib_node_registration_t mcast_prep_node;
36 vlib_node_registration_t mcast_recycle_node;
37
38 static clib_error_t *
39 mcast_test_command_fn (vlib_main_t * vm,
40                  unformat_input_t * input,
41                  vlib_cli_command_t * cmd)
42 {
43   u8 *rewrite_data;
44   mcast_test_main_t * mtm = &mcast_test_main;
45   mcast_main_t * mcm = mtm->mcast_main;
46   ip_adjacency_t adj;
47   u32 adj_index;
48   mcast_group_t * g;
49   mcast_group_member_t * member;
50   unformat_input_t _line_input, * line_input = &_line_input;
51   ip4_address_t dst_addr, zero;
52   ip4_main_t * im = &ip4_main;
53   ip_lookup_main_t * lm = &im->lookup_main;
54
55   /* Get a line of input. */
56   if (! unformat_user (input, unformat_line_input, line_input))
57     return 0;
58
59   pool_get (mcm->groups, g);
60   memset (g, 0, sizeof (*g));
61
62   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
63     {
64       vnet_hw_interface_t *hw;
65       u32 next, sw_if_index;
66
67       if (unformat (line_input, "%U", unformat_vnet_sw_interface, 
68                     mtm->vnet_main, &sw_if_index)) 
69         {
70           vec_add2 (g->members, member, 1);
71           member->tx_sw_if_index = sw_if_index;
72           
73           hw = vnet_get_sup_hw_interface (mtm->vnet_main, 
74                                           sw_if_index);
75           
76           next = vlib_node_add_next (mtm->vlib_main, 
77                                      mcast_prep_node.index,
78                                      hw->output_node_index);
79           
80           /* Required to be the same next index... */
81           vlib_node_add_next_with_slot (mtm->vlib_main,
82                                         mcast_recycle_node.index,
83                                         hw->output_node_index, next);
84           member->prep_and_recycle_node_next_index = next;
85         }
86       else
87         {
88           return unformat_parse_error (line_input);
89         }
90     }
91
92   if (vec_len (g->members) == 0)
93     {
94       pool_put (mcm->groups, g);
95       vlib_cli_output (vm, "no group members specified");
96       return 0;
97     }
98
99
100   adj.lookup_next_index = IP_LOOKUP_NEXT_REWRITE;
101   adj.mcast_group_index = g - mcm->groups;
102   rewrite_data = format (0, "abcdefg");
103
104   vnet_rewrite_for_tunnel
105     (mtm->vnet_main,
106      (u32)~0, /* tx_sw_if_index, we dont know yet */
107      ip4_rewrite_node.index,
108      mcast_prep_node.index,
109      &adj.rewrite_header,
110      rewrite_data, vec_len(rewrite_data));
111
112   ip_add_adjacency (lm, &adj, 1 /* one adj */,
113                     &adj_index);
114   
115   dst_addr.as_u32 = clib_host_to_net_u32 (0x0a000002);
116   zero.as_u32 = 0;
117
118   ip4_add_del_route_next_hop (im,
119                               IP4_ROUTE_FLAG_ADD,
120                               &dst_addr,
121                               24 /* mask width */,
122                               &zero /* no next hop */,
123                           
124                               0, // next hop sw if index
125                               1, // weight
126                               adj_index,
127                               0 /* explicit fib 0 */);
128
129   return 0;
130 }
131
132 static VLIB_CLI_COMMAND (mcast_test_command) = {
133   .path = "test mc",
134   .short_help = "test mc",
135   .function = mcast_test_command_fn,
136 };
137
138 clib_error_t *mcast_test_init (vlib_main_t *vm)
139 {
140   mcast_test_main_t * mtm = &mcast_test_main;
141     
142   mtm->vlib_main = vm;
143   mtm->vnet_main = vnet_get_main();
144   mtm->mcast_main = &mcast_main;
145
146   return 0;
147 }
148
149 VLIB_INIT_FUNCTION (mcast_test_init);