14c047107SPierre Pfister/*
24c047107SPierre Pfister * Copyright (c) 2016 Cisco and/or its affiliates.
34c047107SPierre Pfister * Licensed under the Apache License, Version 2.0 (the "License");
44c047107SPierre Pfister * you may not use this file except in compliance with the License.
54c047107SPierre Pfister * You may obtain a copy of the License at:
64c047107SPierre Pfister *
74c047107SPierre Pfister *     http://www.apache.org/licenses/LICENSE-2.0
84c047107SPierre Pfister *
94c047107SPierre Pfister * Unless required by applicable law or agreed to in writing, software
104c047107SPierre Pfister * distributed under the License is distributed on an "AS IS" BASIS,
114c047107SPierre Pfister * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124c047107SPierre Pfister * See the License for the specific language governing permissions and
134c047107SPierre Pfister * limitations under the License.
144c047107SPierre Pfister */
154c047107SPierre Pfister
164c047107SPierre Pfister#include <librtnl/netns.h>
174c047107SPierre Pfister
184c047107SPierre Pfister#include <vnet/plugin/plugin.h>
194c047107SPierre Pfister#include <librtnl/mapper.h>
204c047107SPierre Pfister#include <vnet/ip/ip.h>
2169ca60e8SPierre Pfister#include <vnet/fib/fib.h>
227e4ce408SPierre Pfister#include <vnet/fib/ip4_fib.h>
237e4ce408SPierre Pfister#include <vnet/fib/ip6_fib.h>
244c047107SPierre Pfister
254c047107SPierre Pfisteru32 handles[10];
264c047107SPierre Pfister
274c047107SPierre Pfisterstatic void
284c047107SPierre Pfistertest_notify(void *obj, netns_type_t type, u32 flags, uword opaque) {
294c047107SPierre Pfister  u32 index = (u32) opaque;
304c047107SPierre Pfister  const char *action = (flags & NETNS_F_ADD)?"add":(flags & NETNS_F_DEL)?"del":"mod";
314c047107SPierre Pfister
324c047107SPierre Pfister  switch (type) {
334c047107SPierre Pfister    case NETNS_TYPE_ADDR:
344c047107SPierre Pfister      clib_warning("%d: addr %s %U", index, action, format_ns_addr, (ns_addr_t *)obj);
354c047107SPierre Pfister      break;
364c047107SPierre Pfister    case NETNS_TYPE_ROUTE:
374c047107SPierre Pfister      clib_warning("%d: route %s %U", index, action, format_ns_route, (ns_route_t *)obj);
384c047107SPierre Pfister      break;
394c047107SPierre Pfister    case NETNS_TYPE_LINK:
404c047107SPierre Pfister      clib_warning("%d:link %s %U", index, action, format_ns_link, (ns_link_t *)obj);
414c047107SPierre Pfister      break;
424c047107SPierre Pfister    case NETNS_TYPE_NEIGH:
434c047107SPierre Pfister      clib_warning("%d: neigh %s %U", index, action, format_ns_neigh, (ns_neigh_t *)obj);
444c047107SPierre Pfister      break;
454c047107SPierre Pfister  }
464c047107SPierre Pfister}
474c047107SPierre Pfister
484c047107SPierre Pfisterstatic clib_error_t *
494c047107SPierre Pfistertest_enable_command_fn (vlib_main_t * vm,
504c047107SPierre Pfister                        unformat_input_t * input,
514c047107SPierre Pfister                        vlib_cli_command_t * cmd)
524c047107SPierre Pfister{
534c047107SPierre Pfister  char *nsname = 0;
544c047107SPierre Pfister  u32 index;
554c047107SPierre Pfister  if (!unformat(input, "%s", &nsname)) {
564c047107SPierre Pfister    return clib_error_return(0, "unknown input `%U'",
574c047107SPierre Pfister                             format_unformat_error, input);
584c047107SPierre Pfister  }
594c047107SPierre Pfister  if (!unformat(input, "%d", &index)) {
604c047107SPierre Pfister    return clib_error_return(0, "unknown input `%U'",
614c047107SPierre Pfister                             format_unformat_error, input);
624c047107SPierre Pfister  }
634c047107SPierre Pfister
644c047107SPierre Pfister  if (!strcmp(nsname, "default"))
654c047107SPierre Pfister    nsname[0] = 0;
664c047107SPierre Pfister
674c047107SPierre Pfister  netns_sub_t sub;
684c047107SPierre Pfister  sub.notify = test_notify;
694c047107SPierre Pfister  sub.opaque = index;
704c047107SPierre Pfister  handles[index] = netns_open(nsname, &sub);
714c047107SPierre Pfister  if (handles[index] == ~0) {
724c047107SPierre Pfister    return clib_error_create("Could not open netns with name %s", nsname);
734c047107SPierre Pfister  }
744c047107SPierre Pfister  return 0;
754c047107SPierre Pfister}
764c047107SPierre Pfister
774c047107SPierre Pfisterstatic clib_error_t *
784c047107SPierre Pfistertest_disable_command_fn (vlib_main_t * vm,
794c047107SPierre Pfister                         unformat_input_t * input,
804c047107SPierre Pfister                         vlib_cli_command_t * cmd)
814c047107SPierre Pfister{
824c047107SPierre Pfister  u32 index;
834c047107SPierre Pfister  if (!unformat(input, "%d", &index)) {
844c047107SPierre Pfister    return clib_error_return(0, "unknown input `%U'",
854c047107SPierre Pfister                             format_unformat_error, input);
864c047107SPierre Pfister  }
874c047107SPierre Pfister
884c047107SPierre Pfister  netns_close(handles[index]);
894c047107SPierre Pfister  return 0;
904c047107SPierre Pfister}
914c047107SPierre Pfister
924c047107SPierre PfisterVLIB_CLI_COMMAND (rtnl_enable_command, static) = {
934c047107SPierre Pfister    .path = "test netns enable",
944c047107SPierre Pfister    .short_help = "test netns enable [<ns-name>|default] <index>",
954c047107SPierre Pfister    .function = test_enable_command_fn,
964c047107SPierre Pfister};
974c047107SPierre Pfister
984c047107SPierre PfisterVLIB_CLI_COMMAND (rtnl_disable_command, static) = {
994c047107SPierre Pfister    .path = "test netns disable",
1004c047107SPierre Pfister    .short_help = "test rtnl disable <index>",
1014c047107SPierre Pfister    .function = test_disable_command_fn,
1024c047107SPierre Pfister};
1034c047107SPierre Pfister
1044c047107SPierre Pfisteru32 mapper_indexes[10];
1054c047107SPierre Pfister
1064c047107SPierre Pfisterstatic clib_error_t *
1074c047107SPierre Pfistermapper_ns_add_command_fn (vlib_main_t * vm,
1084c047107SPierre Pfister                         unformat_input_t * input,
1094c047107SPierre Pfister                         vlib_cli_command_t * cmd)
1104c047107SPierre Pfister{
1114c047107SPierre Pfister  u32 index;
1124c047107SPierre Pfister  char *nsname;
1134c047107SPierre Pfister  u32 table_id;
1144c047107SPierre Pfister  if (!unformat(input, "%d", &index))
1154c047107SPierre Pfister    return clib_error_return(0, "invalid index `%U'",
1164c047107SPierre Pfister                             format_unformat_error, input);
1174c047107SPierre Pfister  if (!unformat(input, "%s", &nsname))
1184c047107SPierre Pfister    return clib_error_return(0, "invalid nsname `%U'",
1194c047107SPierre Pfister                             format_unformat_error, input);
1204c047107SPierre Pfister  if (!unformat(input, "%d", &table_id))
1214c047107SPierre Pfister      return clib_error_return(0, "invalid fib index `%U'",
1224c047107SPierre Pfister                               format_unformat_error, input);
1234c047107SPierre Pfister
1244c047107SPierre Pfister  if (!strcmp(nsname, "default"))
1254c047107SPierre Pfister    nsname[0] = 0;
1264c047107SPierre Pfister
12769ca60e8SPierre Pfister  u32 fib4 = ip4_fib_index_from_table_id(table_id);
12869ca60e8SPierre Pfister  u32 fib6 = ip6_fib_index_from_table_id(table_id);
1294c047107SPierre Pfister
1304c047107SPierre Pfister  if (mapper_add_ns(nsname, fib4, fib6, &mapper_indexes[index]))
1314c047107SPierre Pfister    return clib_error_return(0, "Could not add ns %s", nsname);
1324c047107SPierre Pfister  return 0;
1334c047107SPierre Pfister}
1344c047107SPierre Pfister
1354c047107SPierre PfisterVLIB_CLI_COMMAND (mapper_ns_add_command, static) = {
1364c047107SPierre Pfister    .path = "test mapper ns add",
1374c047107SPierre Pfister    .short_help = "test mapper ns add <index> <nsname> <table-id>",
1384c047107SPierre Pfister    .function = mapper_ns_add_command_fn,
1394c047107SPierre Pfister};
1404c047107SPierre Pfister
1414c047107SPierre Pfisterstatic clib_error_t *
1424c047107SPierre Pfistermapper_ns_del_command_fn (vlib_main_t * vm,
1434c047107SPierre Pfister                         unformat_input_t * input,
1444c047107SPierre Pfister                         vlib_cli_command_t * cmd)
1454c047107SPierre Pfister{
1464c047107SPierre Pfister  u32 index;
1474c047107SPierre Pfister  if (!unformat(input, "%d", &index))
1484c047107SPierre Pfister    return clib_error_return(0, "invalid index `%U'",
1494c047107SPierre Pfister                             format_unformat_error, input);
1504c047107SPierre Pfister
1514c047107SPierre Pfister  if (mapper_del_ns(mapper_indexes[index]))
1524c047107SPierre Pfister    return clib_error_return(0, "Could not del ns %d", index);
1534c047107SPierre Pfister  return 0;
1544c047107SPierre Pfister}
1554c047107SPierre Pfister
1564c047107SPierre PfisterVLIB_CLI_COMMAND (mapper_ns_del_command, static) = {
1574c047107SPierre Pfister    .path = "test mapper ns delete",
1584c047107SPierre Pfister    .short_help = "test mapper ns delete <index>",
1594c047107SPierre Pfister    .function = mapper_ns_del_command_fn,
1604c047107SPierre Pfister};
1614c047107SPierre Pfister
1624c047107SPierre Pfisterstatic clib_error_t *
1634c047107SPierre Pfistermapper_iface_command_fn (vlib_main_t * vm,
1644c047107SPierre Pfister                         unformat_input_t * input,
1654c047107SPierre Pfister                         vlib_cli_command_t * cmd)
1664c047107SPierre Pfister{
1674c047107SPierre Pfister  u32 nsindex;
1684c047107SPierre Pfister  u32 ifindex;
1694c047107SPierre Pfister  u32 sw_if_index;
1704c047107SPierre Pfister  int del = 0;
1714c047107SPierre Pfister  if (!unformat(input, "%d", &nsindex))
1724c047107SPierre Pfister    return clib_error_return(0, "invalid nsindex `%U'",
1734c047107SPierre Pfister                             format_unformat_error, input);
1744c047107SPierre Pfister  if (!unformat(input, "%d", &ifindex))
1754c047107SPierre Pfister    return clib_error_return(0, "invalid ifindex `%U'",
1764c047107SPierre Pfister                             format_unformat_error, input);
1774c047107SPierre Pfister  if (!unformat(input, "%d", &sw_if_index))
1784c047107SPierre Pfister    return clib_error_return(0, "invalid sw_if_index `%U'",
1794c047107SPierre Pfister                             format_unformat_error, input);
1804c047107SPierre Pfister  if (unformat(input, "del"))
1814c047107SPierre Pfister    del = 1;
1824c047107SPierre Pfister
1834c047107SPierre Pfister  clib_warning("mapper_add_del %d %d %d %d", mapper_indexes[nsindex], ifindex, sw_if_index, del);
1844c047107SPierre Pfister
1854c047107SPierre Pfister  if (mapper_add_del(mapper_indexes[nsindex], ifindex, sw_if_index, del))
1864c047107SPierre Pfister    return clib_error_return(0, "Could not add iface");
1874c047107SPierre Pfister  return 0;
1884c047107SPierre Pfister}
1894c047107SPierre Pfister
1904c047107SPierre Pfister
1914c047107SPierre PfisterVLIB_CLI_COMMAND (mapper_iface_command, static) = {
1924c047107SPierre Pfister    .path = "test mapper iface",
1934c047107SPierre Pfister    .short_help = "test mapper iface <nsindex> <linux-ifindex> <sw_if_index> [del]",
1944c047107SPierre Pfister    .function = mapper_iface_command_fn,
1954c047107SPierre Pfister};
1964c047107SPierre Pfister
197ffd58251SHongjun Ni/* *INDENT-OFF* */
198ffd58251SHongjun NiVLIB_PLUGIN_REGISTER () = {
19969ca60e8SPierre Pfister  //.version = VPP_BUILD_VER, FIXME
20069ca60e8SPierre Pfister  .description = "netlink",
201ffd58251SHongjun Ni};
202ffd58251SHongjun Ni/* *INDENT-ON* */
2034c047107SPierre Pfister