Line data Source code
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 4 : 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 4 : fib_prefix_t pfx = {
29 : .fp_len = 128,
30 : .fp_proto = FIB_PROTOCOL_IP6,
31 : .fp_addr = {
32 : .ip6 = *addr,
33 : },
34 : };
35 4 : ip46_address_t nh = {
36 : .ip6 = *addr,
37 : };
38 : /* *INDENT-ON* */
39 :
40 4 : fib_index = ip6_fib_table_get_index_for_sw_if_index (sw_if_index);
41 :
42 4 : if (~0 == fib_index)
43 0 : return VNET_API_ERROR_NO_SUCH_FIB;
44 :
45 4 : if (is_del)
46 : {
47 2 : 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 2 : ip_address_t ip = {
56 : .ip = nh,
57 : .version = AF_IP6,
58 : };
59 2 : ip_neighbor_del (&ip, sw_if_index);
60 : }
61 : else
62 : {
63 2 : 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 4 : return (0);
73 : }
74 :
75 : int
76 2 : ip6_nd_proxy_add (u32 sw_if_index, const ip6_address_t * addr)
77 : {
78 2 : return (ip6_nd_proxy_add_del (sw_if_index, addr, 0));
79 : }
80 :
81 : int
82 2 : ip6_nd_proxy_del (u32 sw_if_index, const ip6_address_t * addr)
83 : {
84 2 : return (ip6_nd_proxy_add_del (sw_if_index, addr, 1));
85 : }
86 :
87 : static clib_error_t *
88 0 : set_ip6_nd_proxy_cmd (vlib_main_t * vm,
89 : unformat_input_t * input, vlib_cli_command_t * cmd)
90 : {
91 0 : vnet_main_t *vnm = vnet_get_main ();
92 0 : clib_error_t *error = 0;
93 : ip6_address_t addr;
94 : u32 sw_if_index;
95 0 : u8 is_del = 0;
96 :
97 0 : if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
98 : {
99 : /* get the rest of the command */
100 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
101 : {
102 0 : if (unformat (input, "%U", unformat_ip6_address, &addr))
103 0 : break;
104 0 : else if (unformat (input, "delete") || unformat (input, "del"))
105 0 : is_del = 1;
106 : else
107 0 : return (unformat_parse_error (input));
108 : }
109 : }
110 : else
111 : {
112 0 : return error;
113 : }
114 :
115 0 : ip6_nd_proxy_add_del (sw_if_index, &addr, is_del);
116 :
117 0 : return error;
118 : }
119 :
120 : /* *INDENT-OFF* */
121 272887 : 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 : */
|