ip6-nd: fix coverity warning
[vpp.git] / src / vnet / ip6-nd / ip6_nd_proxy.c
1 /*
2  * ip/ip6_neighbor.c: IP6 neighbor handling
3  *
4  * Copyright (c) 2010 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <vnet/ip6-nd/ip6_nd.h>
19 #include <vnet/ip-neighbor/ip_neighbor.h>
20
21 #include <vnet/fib/ip6_fib.h>
22
23 static int
24 ip6_nd_proxy_add_del (u32 sw_if_index, const ip6_address_t * addr, u8 is_del)
25 {
26   /* *INDENT-OFF* */
27   u32 fib_index;
28   fib_prefix_t pfx = {
29     .fp_len = 128,
30     .fp_proto = FIB_PROTOCOL_IP6,
31     .fp_addr = {
32       .ip6 = *addr,
33     },
34   };
35   ip46_address_t nh = {
36     .ip6 = *addr,
37   };
38   /* *INDENT-ON* */
39
40   fib_index = ip6_fib_table_get_index_for_sw_if_index (sw_if_index);
41
42   if (~0 == fib_index)
43     return VNET_API_ERROR_NO_SUCH_FIB;
44
45   if (is_del)
46     {
47       fib_table_entry_path_remove (fib_index,
48                                    &pfx,
49                                    FIB_SOURCE_IP6_ND_PROXY,
50                                    DPO_PROTO_IP6,
51                                    &nh,
52                                    sw_if_index,
53                                    ~0, 1, FIB_ROUTE_PATH_FLAG_NONE);
54       /* flush the ND cache of this address if it's there */
55       ip_address_t ip = {
56         .ip = nh,
57         .version = AF_IP6,
58       };
59       ip_neighbor_del (&ip, sw_if_index);
60     }
61   else
62     {
63       fib_table_entry_path_add (fib_index,
64                                 &pfx,
65                                 FIB_SOURCE_IP6_ND_PROXY,
66                                 FIB_ENTRY_FLAG_NONE,
67                                 DPO_PROTO_IP6,
68                                 &nh,
69                                 sw_if_index,
70                                 ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
71     }
72   return (0);
73 }
74
75 int
76 ip6_nd_proxy_add (u32 sw_if_index, const ip6_address_t * addr)
77 {
78   return (ip6_nd_proxy_add_del (sw_if_index, addr, 0));
79 }
80
81 int
82 ip6_nd_proxy_del (u32 sw_if_index, const ip6_address_t * addr)
83 {
84   return (ip6_nd_proxy_add_del (sw_if_index, addr, 1));
85 }
86
87 static clib_error_t *
88 set_ip6_nd_proxy_cmd (vlib_main_t * vm,
89                       unformat_input_t * input, vlib_cli_command_t * cmd)
90 {
91   vnet_main_t *vnm = vnet_get_main ();
92   clib_error_t *error = 0;
93   ip6_address_t addr;
94   u32 sw_if_index;
95   u8 is_del = 0;
96
97   if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
98     {
99       /* get the rest of the command */
100       while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
101         {
102           if (unformat (input, "%U", unformat_ip6_address, &addr))
103             break;
104           else if (unformat (input, "delete") || unformat (input, "del"))
105             is_del = 1;
106           else
107             return (unformat_parse_error (input));
108         }
109     }
110   else
111     {
112       return error;
113     }
114
115   ip6_nd_proxy_add_del (sw_if_index, &addr, is_del);
116
117   return error;
118 }
119
120 /* *INDENT-OFF* */
121 VLIB_CLI_COMMAND (set_ip6_nd_proxy_command, static) =
122 {
123   .path = "set ip6 nd proxy",
124   .short_help = "set ip6 nd proxy <interface> [del] <host-ip>",
125   .function = set_ip6_nd_proxy_cmd,
126 };
127 /* *INDENT-ON* */
128
129 /*
130  * fd.io coding-style-patch-verification: ON
131  *
132  * Local Variables:
133  * eval: (c-set-style "gnu")
134  * End:
135  */