aboutsummaryrefslogtreecommitdiffstats
path: root/extras/router-plugin/devices
diff options
context:
space:
mode:
Diffstat (limited to 'extras/router-plugin/devices')
-rw-r--r--extras/router-plugin/devices/rtnetlink/mapper.c279
-rw-r--r--extras/router-plugin/devices/rtnetlink/mapper.h9
-rw-r--r--extras/router-plugin/devices/rtnetlink/netns.c935
-rw-r--r--extras/router-plugin/devices/rtnetlink/netns.h63
-rw-r--r--extras/router-plugin/devices/rtnetlink/rtnl.c685
-rw-r--r--extras/router-plugin/devices/rtnetlink/rtnl.h24
-rw-r--r--extras/router-plugin/devices/rtnetlink/test.c197
7 files changed, 1170 insertions, 1022 deletions
diff --git a/extras/router-plugin/devices/rtnetlink/mapper.c b/extras/router-plugin/devices/rtnetlink/mapper.c
index ed4fa5634..410d5527d 100644
--- a/extras/router-plugin/devices/rtnetlink/mapper.c
+++ b/extras/router-plugin/devices/rtnetlink/mapper.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -13,254 +13,273 @@
* limitations under the License.
*/
+#include <vnet/fib/fib.h>
#include <vnet/ip/ip.h>
#include <vnet/ip/lookup.h>
-#include <vnet/fib/fib.h>
-#include "netns.h"
#include "mapper.h"
+#include "netns.h"
+#include <hicn/util/sstrncpy.h>
-typedef struct {
+typedef struct
+{
int linux_ifindex;
u32 sw_if_index;
} mapper_map_t;
-typedef struct {
+typedef struct
+{
char nsname[RTNL_NETNS_NAMELEN + 1];
mapper_map_t *mappings;
- u32 netns_handle; //Used to receive notifications
- u32 v4fib_index; //One fib index for the namespace
+ u32 netns_handle; // Used to receive notifications
+ u32 v4fib_index; // One fib index for the namespace
u32 v6fib_index;
} mapper_ns_t;
-typedef struct {
+typedef struct
+{
mapper_ns_t *namespaces;
} mapper_main_t;
static mapper_main_t mapper_main;
-mapper_map_t *mapper_get_by_ifindex(mapper_ns_t *ns, int ifindex)
+mapper_map_t *
+mapper_get_by_ifindex (mapper_ns_t *ns, int ifindex)
{
mapper_map_t *map;
- pool_foreach(map, ns->mappings, {
- if (ifindex == map->linux_ifindex)
- return map;
- });
+ pool_foreach (map, ns->mappings, {
+ if (ifindex == map->linux_ifindex)
+ return map;
+ })
+ ;
return NULL;
}
-int mapper_add_del_route(mapper_ns_t *ns, ns_route_t *route, int del)
+int
+mapper_add_del_route (mapper_ns_t *ns, ns_route_t *route, int del)
{
mapper_main_t *mm = &mapper_main;
- clib_warning("NS %d %s %U", ns - mm->namespaces, del?"del":"add", format_ns_route, route);
+ clib_warning ("NS %d %s %U", ns - mm->namespaces, del ? "del" : "add",
+ format_ns_route, route);
- mapper_map_t *map = mapper_get_by_ifindex(ns, route->oif);
+ mapper_map_t *map = mapper_get_by_ifindex (ns, route->oif);
if (!map)
return 0;
- if (route->rtm.rtm_family == AF_INET6) {
-
- //Filter-out multicast
- if (route->rtm.rtm_dst_len >= 8 && route->dst[0] == 0xff)
- return 0;
-
- fib_prefix_t prefix;
- ip46_address_t nh;
-
- memset (&prefix, 0, sizeof (prefix));
- prefix.fp_len = route->rtm.rtm_dst_len;
- prefix.fp_proto = FIB_PROTOCOL_IP6;
- clib_memcpy (&prefix.fp_addr.ip6, route->dst, sizeof (prefix.fp_addr.ip6));
-
- memset (&nh, 0, sizeof (nh));
- clib_memcpy (&nh.ip6, route->gateway, sizeof (nh.ip6));
-
- fib_table_entry_path_add (ns->v6fib_index, &prefix, FIB_SOURCE_API,
- FIB_ENTRY_FLAG_NONE, prefix.fp_proto,
- &nh, map->sw_if_index, ns->v6fib_index,
- 0 /* weight */,
- (fib_mpls_label_t *) MPLS_LABEL_INVALID,
- FIB_ROUTE_PATH_FLAG_NONE);
- } else {
- fib_prefix_t prefix;
- ip46_address_t nh;
-
- memset (&prefix, 0, sizeof (prefix));
- prefix.fp_len = route->rtm.rtm_dst_len;
- prefix.fp_proto = FIB_PROTOCOL_IP4;
- clib_memcpy (&prefix.fp_addr.ip4, route->dst, sizeof (prefix.fp_addr.ip4));
-
- memset (&nh, 0, sizeof (nh));
- clib_memcpy (&nh.ip4, route->gateway, sizeof (nh.ip4));
-
- fib_table_entry_path_add (ns->v4fib_index, &prefix, FIB_SOURCE_API,
- FIB_ENTRY_FLAG_NONE, prefix.fp_proto,
- &nh, map->sw_if_index, ns->v4fib_index,
- 0 /* weight */,
- (fib_mpls_label_t *) MPLS_LABEL_INVALID,
- FIB_ROUTE_PATH_FLAG_NONE);
- }
+ if (route->rtm.rtm_family == AF_INET6)
+ {
+
+ // Filter-out multicast
+ if (route->rtm.rtm_dst_len >= 8 && route->dst[0] == 0xff)
+ return 0;
+
+ fib_prefix_t prefix;
+ ip_address_t nh;
+
+ memset (&prefix, 0, sizeof (prefix));
+ prefix.fp_len = route->rtm.rtm_dst_len;
+ prefix.fp_proto = FIB_PROTOCOL_IP6;
+ clib_memcpy (&prefix.fp_addr.ip6, route->dst,
+ sizeof (prefix.fp_addr.ip6));
+
+ memset (&nh, 0, sizeof (nh));
+ clib_memcpy (&nh.ip6, route->gateway, sizeof (nh.ip6));
+
+ fib_table_entry_path_add (
+ ns->v6fib_index, &prefix, FIB_SOURCE_API, FIB_ENTRY_FLAG_NONE,
+ prefix.fp_proto, &nh, map->sw_if_index, ns->v6fib_index,
+ 0 /* weight */, (fib_mpls_label_t *) MPLS_LABEL_INVALID,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ }
+ else
+ {
+ fib_prefix_t prefix;
+ ip_address_t nh;
+
+ memset (&prefix, 0, sizeof (prefix));
+ prefix.fp_len = route->rtm.rtm_dst_len;
+ prefix.fp_proto = FIB_PROTOCOL_IP4;
+ clib_memcpy (&prefix.fp_addr.ip4, route->dst,
+ sizeof (prefix.fp_addr.ip4));
+
+ memset (&nh, 0, sizeof (nh));
+ clib_memcpy (&nh.ip4, route->gateway, sizeof (nh.ip4));
+
+ fib_table_entry_path_add (
+ ns->v4fib_index, &prefix, FIB_SOURCE_API, FIB_ENTRY_FLAG_NONE,
+ prefix.fp_proto, &nh, map->sw_if_index, ns->v4fib_index,
+ 0 /* weight */, (fib_mpls_label_t *) MPLS_LABEL_INVALID,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ }
return 0;
}
static void
-mapper_netns_notify_cb(void *obj, netns_type_t type,
- u32 flags, uword opaque)
+mapper_netns_notify_cb (void *obj, netns_type_t type, u32 flags, uword opaque)
{
mapper_main_t *mm = &mapper_main;
mapper_ns_t *ns = &mm->namespaces[(u32) opaque];
- ASSERT(!pool_is_free_index(mm->namespaces, (u32) opaque));
+ ASSERT (!pool_is_free_index (mm->namespaces, (u32) opaque));
if (type != NETNS_TYPE_ROUTE)
- return; //For now...
+ return; // For now...
ns_route_t *route = obj;
- if (flags & NETNS_F_DEL) {
- mapper_add_del_route(ns, route, 1);
- } else if (flags & NETNS_F_ADD) {
- mapper_add_del_route(ns, route, 0);
- }
+ if (flags & NETNS_F_DEL)
+ {
+ mapper_add_del_route (ns, route, 1);
+ }
+ else if (flags & NETNS_F_ADD)
+ {
+ mapper_add_del_route (ns, route, 0);
+ }
}
void
-mapper_delmap(mapper_ns_t*ns, mapper_map_t *map)
+mapper_delmap (mapper_ns_t *ns, mapper_map_t *map)
{
ns_route_t *route;
- netns_t *netns = netns_getns(ns->netns_handle);
- pool_foreach(route, netns->routes, {
- if (route->oif == map->linux_ifindex)
- mapper_add_del_route(ns, route, 1);
- });
- pool_put(ns->mappings, map);
+ netns_t *netns = netns_getns (ns->netns_handle);
+ pool_foreach (route, netns->routes, {
+ if (route->oif == map->linux_ifindex)
+ mapper_add_del_route (ns, route, 1);
+ })
+ ;
+ pool_put (ns->mappings, map);
}
mapper_map_t *
-mapper_getmap(mapper_ns_t*ns, u32 sw_if_index,
- int linux_ifindex, int create)
+mapper_getmap (mapper_ns_t *ns, u32 sw_if_index, int linux_ifindex, int create)
{
mapper_map_t *map;
- pool_foreach(map, ns->mappings, {
- if (linux_ifindex == map->linux_ifindex) {
- if (sw_if_index != map->sw_if_index)
- return NULL; //Cannot have multiple mapping with the same ifindex
- else
- return map;
+ pool_foreach (map, ns->mappings, {
+ if (linux_ifindex == map->linux_ifindex)
+ {
+ if (sw_if_index != map->sw_if_index)
+ return NULL; // Cannot have multiple mapping with the same ifindex
+ else
+ return map;
}
- });
+ })
+ ;
if (!create)
return NULL;
- pool_get(ns->mappings, map);
+ pool_get (ns->mappings, map);
map->linux_ifindex = linux_ifindex;
map->sw_if_index = sw_if_index;
ip6_main.fib_index_by_sw_if_index[sw_if_index] = ns->v6fib_index;
ip4_main.fib_index_by_sw_if_index[sw_if_index] = ns->v4fib_index;
- //Load available routes
+ // Load available routes
ns_route_t *route;
- netns_t *netns = netns_getns(ns->netns_handle);
- pool_foreach(route, netns->routes, {
- if (route->oif == map->linux_ifindex)
- mapper_add_del_route(ns, route, 0);
- });
+ netns_t *netns = netns_getns (ns->netns_handle);
+ pool_foreach (route, netns->routes, {
+ if (route->oif == map->linux_ifindex)
+ mapper_add_del_route (ns, route, 0);
+ })
+ ;
return map;
}
u32
-mapper_get_ns(char *nsname)
+mapper_get_ns (char *nsname)
{
mapper_main_t *mm = &mapper_main;
mapper_ns_t *ns;
- pool_foreach(ns, mm->namespaces, {
- if (!strcmp(nsname, ns->nsname))
- return ns - mm->namespaces;
- });
+ pool_foreach (ns, mm->namespaces, {
+ if (!strcmp (nsname, ns->nsname))
+ return ns - mm->namespaces;
+ })
+ ;
return ~0;
}
int
-mapper_add_del(u32 nsindex, int linux_ifindex,
- u32 sw_if_index, int del)
+mapper_add_del (u32 nsindex, int linux_ifindex, u32 sw_if_index, int del)
{
mapper_main_t *mm = &mapper_main;
- //ip6_main_t *im6 = &ip6_main;
+ // ip6_main_t *im6 = &ip6_main;
mapper_ns_t *ns = &mm->namespaces[nsindex];
mapper_map_t *map;
- //vnet_sw_interface_t *iface = vnet_get_sw_interface(vnet_get_main(), sw_if_index);
+ // vnet_sw_interface_t *iface = vnet_get_sw_interface(vnet_get_main(),
+ // sw_if_index);
- if (pool_is_free(mm->namespaces, ns))
+ if (pool_is_free (mm->namespaces, ns))
return -1;
/*if (!del) {
if ((iface->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) &&
- im6->fib_index_by_sw_if_index[sw_if_index] != ~0) {
+ im6->fib_index_by_sw_if_index[sw_if_index] != ~0) {
//A custom fib index will be used...
- clib_warning("Cannot add interface with a custom fib index (current is %d)",
- im6->fib_index_by_sw_if_index[sw_if_index]);
- return -1;
+ clib_warning("Cannot add interface with a custom fib index (current is
+ %d)", im6->fib_index_by_sw_if_index[sw_if_index]); return -1;
}
}*/
- if (!(map = mapper_getmap(ns, sw_if_index, linux_ifindex, !del)))
+ if (!(map = mapper_getmap (ns, sw_if_index, linux_ifindex, !del)))
return -1;
if (del)
- mapper_delmap(ns, map);
+ mapper_delmap (ns, map);
return 0;
}
int
-mapper_add_ns(char *nsname, u32 v4fib_index, u32 v6fib_index, u32 *nsindex)
+mapper_add_ns (char *nsname, u32 v4fib_index, u32 v6fib_index, u32 *nsindex)
{
mapper_main_t *mm = &mapper_main;
mapper_ns_t *ns;
- if (mapper_get_ns(nsname) != ~0)
- return -1; //Already exists
+ if (mapper_get_ns (nsname) != ~0)
+ return -1; // Already exists
- pool_get(mm->namespaces, ns);
- strcpy(ns->nsname, nsname);
+ pool_get (mm->namespaces, ns);
+ int rc = strcpy_s (ns->nsname, sizeof (ns->nsname), nsname);
+ if (rc != EOK)
+ return -1;
ns->v4fib_index = v4fib_index;
ns->v6fib_index = v6fib_index;
ns->mappings = 0;
netns_sub_t sub;
sub.notify = mapper_netns_notify_cb;
- sub.opaque = (uword)(ns - mm->namespaces);
- if ((ns->netns_handle = netns_open(ns->nsname, &sub)) == ~0) {
- pool_put(mm->namespaces, ns);
- return -1;
- }
+ sub.opaque = (uword) (ns - mm->namespaces);
+ if ((ns->netns_handle = netns_open (ns->nsname, &sub)) == ~0)
+ {
+ pool_put (mm->namespaces, ns);
+ return -1;
+ }
*nsindex = ns - mm->namespaces;
return 0;
}
int
-mapper_del_ns(u32 nsindex)
+mapper_del_ns (u32 nsindex)
{
mapper_main_t *mm = &mapper_main;
mapper_ns_t *ns = &mm->namespaces[nsindex];
- if (pool_is_free(mm->namespaces, ns))
+ if (pool_is_free (mm->namespaces, ns))
return -1;
- //Remove all existing mappings
+ // Remove all existing mappings
int i, *indexes = 0;
- pool_foreach_index(i, ns->mappings, {
- vec_add1(indexes, i);
- });
- vec_foreach_index(i, indexes) {
- mapper_delmap(ns, &ns->mappings[indexes[i]]);
- }
- vec_free(indexes);
-
- netns_close(ns->netns_handle);
- pool_put(mm->namespaces, ns);
+ pool_foreach_index (i, ns->mappings, { vec_add1 (indexes, i); })
+ ;
+ vec_foreach_index (i, indexes)
+ {
+ mapper_delmap (ns, &ns->mappings[indexes[i]]);
+ }
+ vec_free (indexes);
+
+ netns_close (ns->netns_handle);
+ pool_put (mm->namespaces, ns);
return 0;
}
clib_error_t *
-mapper_init (vlib_main_t * vm)
+mapper_init (vlib_main_t *vm)
{
mapper_main_t *mm = &mapper_main;
mm->namespaces = 0;
diff --git a/extras/router-plugin/devices/rtnetlink/mapper.h b/extras/router-plugin/devices/rtnetlink/mapper.h
index 32e95d48f..436e5dc4d 100644
--- a/extras/router-plugin/devices/rtnetlink/mapper.h
+++ b/extras/router-plugin/devices/rtnetlink/mapper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -28,8 +28,9 @@
* A mapped VPP interface must not have any configured fib.
*/
-int mapper_add_ns(char *nsname, u32 v4fib_index, u32 v6fib_index, u32 *nsindex);
-int mapper_del_ns(u32 nsindex);
-int mapper_add_del(u32 nsindex, int linux_ifindex, u32 sw_if_index, int del);
+int mapper_add_ns (char *nsname, u32 v4fib_index, u32 v6fib_index,
+ u32 *nsindex);
+int mapper_del_ns (u32 nsindex);
+int mapper_add_del (u32 nsindex, int linux_ifindex, u32 sw_if_index, int del);
#endif /* MAPPER_H_ */
diff --git a/extras/router-plugin/devices/rtnetlink/netns.c b/extras/router-plugin/devices/rtnetlink/netns.c
index 19adb469a..0d9986185 100644
--- a/extras/router-plugin/devices/rtnetlink/netns.c
+++ b/extras/router-plugin/devices/rtnetlink/netns.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -13,190 +13,197 @@
* limitations under the License.
*/
-
-#include <vlib/vlib.h>
+#include <stddef.h>
#include <vlib/unix/unix.h>
+#include <vlib/vlib.h>
#include <vnet/ethernet/ethernet.h>
+#include <vnet/ip/format.h>
#include <vnet/ip/ip4_packet.h>
#include <vnet/ip/ip6_packet.h>
-#include <vnet/ip/format.h>
-#include <stddef.h>
#include "netns.h"
+#include <hicn/util/sstrncpy.h>
/* Enable some RTA values debug */
//#define RTNL_CHECK
-#define is_nonzero(x) \
- ({ \
- u8 __is_zero_zero[sizeof(x)] = {}; \
- memcmp(__is_zero_zero, &x, sizeof(x)); \
+#define is_nonzero(x) \
+ ({ \
+ u8 __is_zero_zero[sizeof (x)] = {}; \
+ memcmp (__is_zero_zero, &x, sizeof (x)); \
})
-typedef struct {
- u8 type; //Attribute identifier
- u8 unique; //Part of the values uniquely identifying an entry
- u16 offset; //Offset where stored in struct
- u16 size; //Length of the attribute
+typedef struct
+{
+ u8 type; // Attribute identifier
+ u8 unique; // Part of the values uniquely identifying an entry
+ u16 offset; // Offset where stored in struct
+ u16 size; // Length of the attribute
} rtnl_mapping_t;
-#define ns_foreach_ifla \
- _(IFLA_ADDRESS, hwaddr) \
- _(IFLA_BROADCAST, broadcast) \
- _(IFLA_IFNAME, ifname) \
- _(IFLA_MASTER, master) \
- _(IFLA_MTU, mtu) \
- _(IFLA_QDISC, qdisc)
+#define ns_foreach_ifla \
+ _ (IFLA_ADDRESS, hwaddr) \
+ _ (IFLA_BROADCAST, broadcast) \
+ _ (IFLA_IFNAME, ifname) \
+ _ (IFLA_MASTER, master) \
+ _ (IFLA_MTU, mtu) \
+ _ (IFLA_QDISC, qdisc)
static rtnl_mapping_t ns_ifmap[] = {
-#define _(t, e) \
- { \
- .type = t, \
- .offset = offsetof(ns_link_t, e), \
- .size = sizeof(((ns_link_t*)0)->e) \
- },
+#define _(t, e) \
+ { .type = t, \
+ .offset = offsetof (ns_link_t, e), \
+ .size = sizeof (((ns_link_t *) 0)->e) },
ns_foreach_ifla
#undef _
{ .type = 0 }
};
-u8 *format_ns_link (u8 *s, va_list *args)
+u8 *
+format_ns_link (u8 *s, va_list *args)
{
- ns_link_t *l = va_arg(*args, ns_link_t *);
- s = format(s, "%s index %u", l->ifname, l->ifi.ifi_index);
+ ns_link_t *l = va_arg (*args, ns_link_t *);
+ s = format (s, "%s index %u", l->ifname, l->ifi.ifi_index);
return s;
}
-#define ns_foreach_rta \
- _(RTA_DST, dst, 1) \
- _(RTA_SRC, src, 1) \
- _(RTA_GATEWAY, gateway, 1) \
- _(RTA_IIF, iif, 1) \
- _(RTA_OIF, oif, 1) \
- _(RTA_PREFSRC, prefsrc, 0) \
- _(RTA_TABLE, table, 0) \
- _(RTA_PRIORITY, priority, 0) \
- _(RTA_CACHEINFO, cacheinfo, 0) \
- _(RTA_ENCAP, encap, 1)
+#define ns_foreach_rta \
+ _ (RTA_DST, dst, 1) \
+ _ (RTA_SRC, src, 1) \
+ _ (RTA_GATEWAY, gateway, 1) \
+ _ (RTA_IIF, iif, 1) \
+ _ (RTA_OIF, oif, 1) \
+ _ (RTA_PREFSRC, prefsrc, 0) \
+ _ (RTA_TABLE, table, 0) \
+ _ (RTA_PRIORITY, priority, 0) \
+ _ (RTA_CACHEINFO, cacheinfo, 0) \
+ _ (RTA_ENCAP, encap, 1)
static rtnl_mapping_t ns_routemap[] = {
-#define _(t, e, u) \
- { \
- .type = t, .unique = u, \
- .offset = offsetof(ns_route_t, e), \
- .size = sizeof(((ns_route_t*)0)->e) \
- },
+#define _(t, e, u) \
+ { .type = t, \
+ .unique = u, \
+ .offset = offsetof (ns_route_t, e), \
+ .size = sizeof (((ns_route_t *) 0)->e) },
ns_foreach_rta
#undef _
{ .type = 0 }
};
-u8 *format_ns_route (u8 *s, va_list *args)
+u8 *
+format_ns_route (u8 *s, va_list *args)
{
- ns_route_t *r = va_arg(*args, ns_route_t *);
- void *format_ip = r->rtm.rtm_family == AF_INET ? format_ip4_address : format_ip6_address;
- s = format(s, "%U/%d", format_ip, r->dst, r->rtm.rtm_dst_len);
+ ns_route_t *r = va_arg (*args, ns_route_t *);
+ void *format_ip =
+ r->rtm.rtm_family == AF_INET ? format_ip4_address : format_ip6_address;
+ s = format (s, "%U/%d", format_ip, r->dst, r->rtm.rtm_dst_len);
if (r->rtm.rtm_src_len)
- s = format(s, " from %U/%d", format_ip, r->src, r->rtm.rtm_src_len);
- if (is_nonzero(r->gateway))
- s = format(s, " via %U", format_ip, r->gateway);
+ s = format (s, " from %U/%d", format_ip, r->src, r->rtm.rtm_src_len);
+ if (is_nonzero (r->gateway))
+ s = format (s, " via %U", format_ip, r->gateway);
if (r->iif)
- s = format(s, " iif %d", r->iif);
+ s = format (s, " iif %d", r->iif);
if (r->oif)
- s = format(s, " oif %d", r->oif);
- if (is_nonzero(r->prefsrc))
- s = format(s, " src %U", format_ip, r->prefsrc);
+ s = format (s, " oif %d", r->oif);
+ if (is_nonzero (r->prefsrc))
+ s = format (s, " src %U", format_ip, r->prefsrc);
if (r->table)
- s = format(s, " table %d", r->table);
+ s = format (s, " table %d", r->table);
if (r->priority)
- s = format(s, " priority %u", r->priority);
+ s = format (s, " priority %u", r->priority);
return s;
}
-#define ns_foreach_ifaddr \
- _(IFA_ADDRESS, addr, 1) \
- _(IFA_LOCAL, local, 1) \
- _(IFA_LABEL, label, 0) \
- _(IFA_BROADCAST, broadcast, 0) \
- _(IFA_ANYCAST, anycast, 0) \
- _(IFA_CACHEINFO, cacheinfo, 0)
+#define ns_foreach_ifaddr \
+ _ (IFA_ADDRESS, addr, 1) \
+ _ (IFA_LOCAL, local, 1) \
+ _ (IFA_LABEL, label, 0) \
+ _ (IFA_BROADCAST, broadcast, 0) \
+ _ (IFA_ANYCAST, anycast, 0) \
+ _ (IFA_CACHEINFO, cacheinfo, 0)
static rtnl_mapping_t ns_addrmap[] = {
-#define _(t, e, u) \
- { \
- .type = t, .unique = u, \
- .offset = offsetof(ns_addr_t, e), \
- .size = sizeof(((ns_addr_t*)0)->e) \
- },
+#define _(t, e, u) \
+ { .type = t, \
+ .unique = u, \
+ .offset = offsetof (ns_addr_t, e), \
+ .size = sizeof (((ns_addr_t *) 0)->e) },
ns_foreach_ifaddr
#undef _
{ .type = 0 }
};
-u8 *format_ns_addr (u8 *s, va_list *args)
-{
- ns_addr_t *a = va_arg(*args, ns_addr_t *);
- void *format_ip = a->ifaddr.ifa_family == AF_INET ? format_ip4_address : format_ip6_address;
- s = format(s, "%U/%d", format_ip, a->addr, a->ifaddr.ifa_prefixlen);
- if (is_nonzero(a->label))
- s = format(s, " dev %s", a->label);
- if (is_nonzero(a->broadcast))
- s = format(s, " broadcast %U", format_ip, a->broadcast);
- if (is_nonzero(a->anycast))
- s = format(s, " anycast %U", format_ip, a->anycast);
- if (is_nonzero(a->local))
- s = format(s, " local %U", format_ip, a->local);
+u8 *
+format_ns_addr (u8 *s, va_list *args)
+{
+ ns_addr_t *a = va_arg (*args, ns_addr_t *);
+ void *format_ip =
+ a->ifaddr.ifa_family == AF_INET ? format_ip4_address : format_ip6_address;
+ s = format (s, "%U/%d", format_ip, a->addr, a->ifaddr.ifa_prefixlen);
+ if (is_nonzero (a->label))
+ s = format (s, " dev %s", a->label);
+ if (is_nonzero (a->broadcast))
+ s = format (s, " broadcast %U", format_ip, a->broadcast);
+ if (is_nonzero (a->anycast))
+ s = format (s, " anycast %U", format_ip, a->anycast);
+ if (is_nonzero (a->local))
+ s = format (s, " local %U", format_ip, a->local);
return s;
}
#ifndef NDA_RTA
-#define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
-#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
+#define NDA_RTA(r) \
+ ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN (sizeof (struct ndmsg))))
+#define NDA_PAYLOAD(n) NLMSG_PAYLOAD (n, sizeof (struct ndmsg))
#endif
-#define ns_foreach_neigh \
- _(NDA_DST, dst, 1) \
- _(NDA_LLADDR, lladdr, 0) \
- _(NDA_PROBES, probes, 0) \
- _(NDA_CACHEINFO, cacheinfo, 0)
+#define ns_foreach_neigh \
+ _ (NDA_DST, dst, 1) \
+ _ (NDA_LLADDR, lladdr, 0) \
+ _ (NDA_PROBES, probes, 0) \
+ _ (NDA_CACHEINFO, cacheinfo, 0)
static rtnl_mapping_t ns_neighmap[] = {
-#define _(t, e, u) \
- { \
- .type = t, .unique = u, \
- .offset = offsetof(ns_neigh_t, e), \
- .size = sizeof(((ns_neigh_t*)0)->e) \
- },
+#define _(t, e, u) \
+ { .type = t, \
+ .unique = u, \
+ .offset = offsetof (ns_neigh_t, e), \
+ .size = sizeof (((ns_neigh_t *) 0)->e) },
ns_foreach_neigh
#undef _
{ .type = 0 }
};
-u8 *format_ns_neigh (u8 *s, va_list *args)
+u8 *
+format_ns_neigh (u8 *s, va_list *args)
{
- ns_neigh_t *n = va_arg(*args, ns_neigh_t *);
- void *format_ip = n->nd.ndm_family == AF_INET ? format_ip4_address : format_ip6_address;
- s = format(s, "%U", format_ip, n->dst);
- if (is_nonzero(n->lladdr))
- s = format(s, " lladdr %U", format_ethernet_address, n->lladdr);
+ ns_neigh_t *n = va_arg (*args, ns_neigh_t *);
+ void *format_ip =
+ n->nd.ndm_family == AF_INET ? format_ip4_address : format_ip6_address;
+ s = format (s, "%U", format_ip, n->dst);
+ if (is_nonzero (n->lladdr))
+ s = format (s, " lladdr %U", format_ethernet_address, n->lladdr);
if (n->probes)
- s = format(s, " probes %d", n->probes);
+ s = format (s, " probes %d", n->probes);
return s;
}
-typedef struct {
- void (*notify)(void *obj, netns_type_t type, u32 flags, uword opaque);
+typedef struct
+{
+ void (*notify) (void *obj, netns_type_t type, u32 flags, uword opaque);
uword opaque;
u32 netns_index;
} netns_handle_t;
-typedef struct {
+typedef struct
+{
netns_t netns;
u32 rtnl_handle;
u32 subscriber_count;
} netns_p;
-typedef struct {
+typedef struct
+{
netns_p *netnss;
netns_handle_t *handles;
} netns_main_t;
@@ -204,22 +211,25 @@ typedef struct {
netns_main_t netns_main;
static int
-rtnl_parse_rtattr(struct rtattr *db[], size_t max,
- struct rtattr *rta, size_t len) {
- for(; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
- if (rta->rta_type <= max)
- db[rta->rta_type] = rta;
+rtnl_parse_rtattr (struct rtattr *db[], size_t max, struct rtattr *rta,
+ size_t len)
+{
+ for (; RTA_OK (rta, len); rta = RTA_NEXT (rta, len))
+ {
+ if (rta->rta_type <= max)
+ db[rta->rta_type] = rta;
#ifdef RTNL_CHECK
- else
- clib_warning("RTA type too high: %d", rta->rta_type);
+ else
+ clib_warning ("RTA type too high: %d", rta->rta_type);
#endif
- }
+ }
- if(len) {
- clib_warning("rattr lenght mistmatch %d %d len",
- (int) len, (int) rta->rta_len);
- return -1;
- }
+ if (len)
+ {
+ clib_warning ("rattr lenght mistmatch %d %d len", (int) len,
+ (int) rta->rta_len);
+ return -1;
+ }
return 0;
}
@@ -230,24 +240,24 @@ rtnl_parse_rtattr(struct rtattr *db[], size_t max,
*/
#ifdef RTNL_CHECK
static void
-rtnl_entry_check(struct rtattr *rtas[],
- size_t rta_len,
- rtnl_mapping_t map[],
- char *logstr)
+rtnl_entry_check (struct rtattr *rtas[], size_t rta_len, rtnl_mapping_t map[],
+ char *logstr)
{
int i;
- for (i=0; i<rta_len; i++) {
- if (!rtas[i])
- continue;
-
- rtnl_mapping_t *m = map;
- for (m = map; m->type; m++) {
- if (m->type == rtas[i]->rta_type)
- break;
+ for (i = 0; i < rta_len; i++)
+ {
+ if (!rtas[i])
+ continue;
+
+ rtnl_mapping_t *m = map;
+ for (m = map; m->type; m++)
+ {
+ if (m->type == rtas[i]->rta_type)
+ break;
+ }
+ if (!m->type)
+ clib_warning ("Unknown RTA type %d (%s)", rtas[i]->rta_type, logstr);
}
- if (!m->type)
- clib_warning("Unknown RTA type %d (%s)", rtas[i]->rta_type, logstr);
- }
}
#endif
@@ -255,433 +265,469 @@ rtnl_entry_check(struct rtattr *rtas[],
* Check if the provided entry matches the parsed and unique rtas
*/
static int
-rtnl_entry_match(void *entry,
- struct rtattr *rtas[],
- rtnl_mapping_t map[])
+rtnl_entry_match (void *entry, struct rtattr *rtas[], rtnl_mapping_t map[])
{
u8 zero[1024] = {};
- for ( ;map->type != 0; map++) {
- struct rtattr *rta = rtas[map->type];
- size_t rta_len = rta?RTA_PAYLOAD(rta):0;
- if (!map->unique)
- continue;
-
- if (rta && RTA_PAYLOAD(rta) > map->size) {
- clib_warning("rta (type=%d len=%d) too long (max %d)",
- rta->rta_type, rta->rta_len, map->size);
- return -1;
- }
-
- if ((rta && memcmp(RTA_DATA(rta), entry + map->offset, rta_len)) ||
- memcmp(entry + map->offset + rta_len, zero, map->size - rta_len)) {
- return 0;
+ for (; map->type != 0; map++)
+ {
+ struct rtattr *rta = rtas[map->type];
+ size_t rta_len = rta ? RTA_PAYLOAD (rta) : 0;
+ if (!map->unique)
+ continue;
+
+ if (rta && RTA_PAYLOAD (rta) > map->size)
+ {
+ clib_warning ("rta (type=%d len=%d) too long (max %d)",
+ rta->rta_type, rta->rta_len, map->size);
+ return -1;
+ }
+
+ if ((rta && memcmp (RTA_DATA (rta), entry + map->offset, rta_len)) ||
+ memcmp (entry + map->offset + rta_len, zero, map->size - rta_len))
+ {
+ return 0;
+ }
}
- }
return 1;
}
static int
-rtnl_entry_set(void *entry,
- struct rtattr *rtas[],
- rtnl_mapping_t map[],
- int init)
-{
- for (; map->type != 0; map++) {
-
- struct rtattr *rta = rtas[map->type];
-
- if(map->type == RTA_ENCAP && rta) {
- /*Data of RTA_ENCAP is a pointer to rta attributes for MPLS*/
- rta = (struct rtattr*)RTA_DATA(rta);
- if (RTA_PAYLOAD(rta) > map->size) {
- clib_warning("rta (type=%d len=%d) too long (max %d)", rta->rta_type, rta->rta_len, map->size);
- return -1;
- }
- memcpy(entry + map->offset, RTA_DATA(rta), map->size);
- memset(entry + map->offset + map->size, 0, 0);
- } else if (rta) {
- if (RTA_PAYLOAD(rta) > map->size) {
- clib_warning("rta (type=%d len=%d) too long (max %d)", rta->rta_type, rta->rta_len, map->size);
- return -1;
- }
- memcpy(entry + map->offset, RTA_DATA(rta), RTA_PAYLOAD(rta));
- memset(entry + map->offset + RTA_PAYLOAD(rta), 0, map->size - RTA_PAYLOAD(rta));
- } else if (init) {
- memset(entry + map->offset, 0, map->size);
+rtnl_entry_set (void *entry, struct rtattr *rtas[], rtnl_mapping_t map[],
+ int init)
+{
+ for (; map->type != 0; map++)
+ {
+
+ struct rtattr *rta = rtas[map->type];
+
+ if (map->type == RTA_ENCAP && rta)
+ {
+ /*Data of RTA_ENCAP is a pointer to rta attributes for MPLS*/
+ rta = (struct rtattr *) RTA_DATA (rta);
+ if (RTA_PAYLOAD (rta) > map->size)
+ {
+ clib_warning ("rta (type=%d len=%d) too long (max %d)",
+ rta->rta_type, rta->rta_len, map->size);
+ return -1;
+ }
+ memcpy (entry + map->offset, RTA_DATA (rta), map->size);
+ memset (entry + map->offset + map->size, 0, 0);
+ }
+ else if (rta)
+ {
+ if (RTA_PAYLOAD (rta) > map->size)
+ {
+ clib_warning ("rta (type=%d len=%d) too long (max %d)",
+ rta->rta_type, rta->rta_len, map->size);
+ return -1;
+ }
+ memcpy (entry + map->offset, RTA_DATA (rta), RTA_PAYLOAD (rta));
+ memset (entry + map->offset + RTA_PAYLOAD (rta), 0,
+ map->size - RTA_PAYLOAD (rta));
+ }
+ else if (init)
+ {
+ memset (entry + map->offset, 0, map->size);
+ }
}
- }
return 0;
}
void
-netns_notify(netns_p *ns, void *obj, netns_type_t type, u32 flags)
+netns_notify (netns_p *ns, void *obj, netns_type_t type, u32 flags)
{
netns_main_t *nm = &netns_main;
netns_handle_t *h;
- pool_foreach(h, nm->handles, {
- if (h->netns_index == (ns - nm->netnss) && h->notify)
- h->notify(obj, type, flags, h->opaque);
- });
+ pool_foreach (h, nm->handles, {
+ if (h->netns_index == (ns - nm->netnss) && h->notify)
+ h->notify (obj, type, flags, h->opaque);
+ })
+ ;
}
static_always_inline int
-mask_match(void *a, void *b, void *mask, size_t len)
+mask_match (void *a, void *b, void *mask, size_t len)
{
u8 *va = (u8 *) a;
u8 *vb = (u8 *) b;
u8 *vm = (u8 *) mask;
- while (len--) {
- if ((va[len] ^ vb[len]) & vm[len])
- return 0;
- }
+ while (len--)
+ {
+ if ((va[len] ^ vb[len]) & vm[len])
+ return 0;
+ }
return 1;
}
static ns_link_t *
-ns_get_link(netns_p *ns, struct ifinfomsg *ifi, struct rtattr *rtas[])
+ns_get_link (netns_p *ns, struct ifinfomsg *ifi, struct rtattr *rtas[])
{
ns_link_t *link;
- pool_foreach(link, ns->netns.links, {
- if(ifi->ifi_index == link->ifi.ifi_index)
- return link;
- });
+ pool_foreach (link, ns->netns.links, {
+ if (ifi->ifi_index == link->ifi.ifi_index)
+ return link;
+ })
+ ;
return NULL;
}
static int
-ns_rcv_link(netns_p *ns, struct nlmsghdr *hdr)
+ns_rcv_link (netns_p *ns, struct nlmsghdr *hdr)
{
ns_link_t *link;
struct ifinfomsg *ifi;
struct rtattr *rtas[IFLA_MAX + 1] = {};
- size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN(sizeof(*hdr));
+ size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN (sizeof (*hdr));
- if(datalen < sizeof(*ifi))
+ if (datalen < sizeof (*ifi))
return -1;
- ifi = NLMSG_DATA(hdr);
- if((datalen > NLMSG_ALIGN(sizeof(*ifi))) &&
- rtnl_parse_rtattr(rtas, IFLA_MAX, IFLA_RTA(ifi),
- IFLA_PAYLOAD(hdr))) {
- return -1;
- }
+ ifi = NLMSG_DATA (hdr);
+ if ((datalen > NLMSG_ALIGN (sizeof (*ifi))) &&
+ rtnl_parse_rtattr (rtas, IFLA_MAX, IFLA_RTA (ifi), IFLA_PAYLOAD (hdr)))
+ {
+ return -1;
+ }
#ifdef RTNL_CHECK
- rtnl_entry_check(rtas, IFLA_MAX + 1, ns_ifmap, "link");
+ rtnl_entry_check (rtas, IFLA_MAX + 1, ns_ifmap, "link");
#endif
- link = ns_get_link(ns, ifi, rtas);
+ link = ns_get_link (ns, ifi, rtas);
- if (hdr->nlmsg_type == RTM_DELLINK) {
- if (!link)
- return -1;
- pool_put(ns->netns.links, link);
- netns_notify(ns, link, NETNS_TYPE_LINK, NETNS_F_DEL);
- return 0;
- }
-
- if (!link) {
- pool_get(ns->netns.links, link);
- rtnl_entry_set(link, rtas, ns_ifmap, 1);
- } else {
- rtnl_entry_set(link, rtas, ns_ifmap, 0);
- }
+ if (hdr->nlmsg_type == RTM_DELLINK)
+ {
+ if (!link)
+ return -1;
+ pool_put (ns->netns.links, link);
+ netns_notify (ns, link, NETNS_TYPE_LINK, NETNS_F_DEL);
+ return 0;
+ }
+
+ if (!link)
+ {
+ pool_get (ns->netns.links, link);
+ rtnl_entry_set (link, rtas, ns_ifmap, 1);
+ }
+ else
+ {
+ rtnl_entry_set (link, rtas, ns_ifmap, 0);
+ }
link->ifi = *ifi;
- link->last_updated = vlib_time_now(vlib_get_main());
- netns_notify(ns, link, NETNS_TYPE_LINK, NETNS_F_ADD);
+ link->last_updated = vlib_time_now (vlib_get_main ());
+ netns_notify (ns, link, NETNS_TYPE_LINK, NETNS_F_ADD);
return 0;
}
static ns_route_t *
-ns_get_route(netns_p *ns, struct rtmsg *rtm, struct rtattr *rtas[])
+ns_get_route (netns_p *ns, struct rtmsg *rtm, struct rtattr *rtas[])
{
ns_route_t *route;
- //This describes the values which uniquely identify a route
- struct rtmsg msg = {
- .rtm_family = 0xff,
- .rtm_dst_len = 0xff,
- .rtm_src_len = 0xff,
- .rtm_table = 0xff,
- .rtm_protocol = 0xff,
- .rtm_type = 0xff
- };
-
- pool_foreach(route, ns->netns.routes, {
- if(mask_match(&route->rtm, rtm, &msg, sizeof(struct rtmsg)) &&
- rtnl_entry_match(route, rtas, ns_routemap))
- return route;
- });
+ // This describes the values which uniquely identify a route
+ struct rtmsg msg = { .rtm_family = 0xff,
+ .rtm_dst_len = 0xff,
+ .rtm_src_len = 0xff,
+ .rtm_table = 0xff,
+ .rtm_protocol = 0xff,
+ .rtm_type = 0xff };
+
+ pool_foreach (route, ns->netns.routes, {
+ if (mask_match (&route->rtm, rtm, &msg, sizeof (struct rtmsg)) &&
+ rtnl_entry_match (route, rtas, ns_routemap))
+ return route;
+ })
+ ;
return NULL;
}
static int
-ns_rcv_route(netns_p *ns, struct nlmsghdr *hdr)
+ns_rcv_route (netns_p *ns, struct nlmsghdr *hdr)
{
ns_route_t *route;
struct rtmsg *rtm;
struct rtattr *rtas[RTA_MAX + 1] = {};
- size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN(sizeof(*hdr));
+ size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN (sizeof (*hdr));
- if(datalen < sizeof(*rtm))
+ if (datalen < sizeof (*rtm))
return -1;
- rtm = NLMSG_DATA(hdr);
- if((datalen > NLMSG_ALIGN(sizeof(*rtm))) &&
- rtnl_parse_rtattr(rtas, RTA_MAX, RTM_RTA(rtm),
- RTM_PAYLOAD(hdr))) {
- return -1;
- }
+ rtm = NLMSG_DATA (hdr);
+ if ((datalen > NLMSG_ALIGN (sizeof (*rtm))) &&
+ rtnl_parse_rtattr (rtas, RTA_MAX, RTM_RTA (rtm), RTM_PAYLOAD (hdr)))
+ {
+ return -1;
+ }
#ifdef RTNL_CHECK
- rtnl_entry_check(rtas, RTA_MAX + 1, ns_routemap, "route");
+ rtnl_entry_check (rtas, RTA_MAX + 1, ns_routemap, "route");
#endif
- route = ns_get_route(ns, rtm, rtas);
+ route = ns_get_route (ns, rtm, rtas);
+
+ if (hdr->nlmsg_type == RTM_DELROUTE)
+ {
+ if (!route)
+ return -1;
+ pool_put (ns->netns.routes, route);
+ netns_notify (ns, route, NETNS_TYPE_ROUTE, NETNS_F_DEL);
+ return 0;
+ }
- if (hdr->nlmsg_type == RTM_DELROUTE) {
- if (!route)
- return -1;
- pool_put(ns->netns.routes, route);
- netns_notify(ns, route, NETNS_TYPE_ROUTE, NETNS_F_DEL);
- return 0;
- }
-
- if (!route) {
- pool_get(ns->netns.routes, route);
- memset(route, 0, sizeof(*route));
- rtnl_entry_set(route, rtas, ns_routemap, 1);
- } else {
- rtnl_entry_set(route, rtas, ns_routemap, 0);
- }
+ if (!route)
+ {
+ pool_get (ns->netns.routes, route);
+ memset (route, 0, sizeof (*route));
+ rtnl_entry_set (route, rtas, ns_routemap, 1);
+ }
+ else
+ {
+ rtnl_entry_set (route, rtas, ns_routemap, 0);
+ }
route->rtm = *rtm;
- route->last_updated = vlib_time_now(vlib_get_main());
- netns_notify(ns, route, NETNS_TYPE_ROUTE, NETNS_F_ADD);
+ route->last_updated = vlib_time_now (vlib_get_main ());
+ netns_notify (ns, route, NETNS_TYPE_ROUTE, NETNS_F_ADD);
return 0;
}
static ns_addr_t *
-ns_get_addr(netns_p *ns, struct ifaddrmsg *ifaddr, struct rtattr *rtas[])
+ns_get_addr (netns_p *ns, struct ifaddrmsg *ifaddr, struct rtattr *rtas[])
{
ns_addr_t *addr;
- //This describes the values which uniquely identify a route
+ // This describes the values which uniquely identify a route
struct ifaddrmsg msg = {
.ifa_family = 0xff,
.ifa_prefixlen = 0xff,
};
- pool_foreach(addr, ns->netns.addresses, {
- if(mask_match(&addr->ifaddr, ifaddr, &msg, sizeof(struct ifaddrmsg)) &&
- rtnl_entry_match(addr, rtas, ns_addrmap))
- return addr;
- });
+ pool_foreach (addr, ns->netns.addresses, {
+ if (mask_match (&addr->ifaddr, ifaddr, &msg, sizeof (struct ifaddrmsg)) &&
+ rtnl_entry_match (addr, rtas, ns_addrmap))
+ return addr;
+ })
+ ;
return NULL;
}
static int
-ns_rcv_addr(netns_p *ns, struct nlmsghdr *hdr)
+ns_rcv_addr (netns_p *ns, struct nlmsghdr *hdr)
{
ns_addr_t *addr;
struct ifaddrmsg *ifaddr;
struct rtattr *rtas[IFA_MAX + 1] = {};
- size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN(sizeof(*hdr));
+ size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN (sizeof (*hdr));
- if(datalen < sizeof(*ifaddr))
+ if (datalen < sizeof (*ifaddr))
return -1;
- ifaddr = NLMSG_DATA(hdr);
- if((datalen > NLMSG_ALIGN(sizeof(*ifaddr))) &&
- rtnl_parse_rtattr(rtas, IFA_MAX, IFA_RTA(ifaddr),
- IFA_PAYLOAD(hdr))) {
- return -1;
- }
+ ifaddr = NLMSG_DATA (hdr);
+ if ((datalen > NLMSG_ALIGN (sizeof (*ifaddr))) &&
+ rtnl_parse_rtattr (rtas, IFA_MAX, IFA_RTA (ifaddr), IFA_PAYLOAD (hdr)))
+ {
+ return -1;
+ }
#ifdef RTNL_CHECK
- rtnl_entry_check(rtas, IFA_MAX + 1, ns_addrmap, "addr");
+ rtnl_entry_check (rtas, IFA_MAX + 1, ns_addrmap, "addr");
#endif
- addr = ns_get_addr(ns, ifaddr, rtas);
+ addr = ns_get_addr (ns, ifaddr, rtas);
+
+ if (hdr->nlmsg_type == RTM_DELADDR)
+ {
+ if (!addr)
+ return -1;
+ pool_put (ns->netns.addresses, addr);
+ netns_notify (ns, addr, NETNS_TYPE_ADDR, NETNS_F_DEL);
+ return 0;
+ }
- if (hdr->nlmsg_type == RTM_DELADDR) {
- if (!addr)
- return -1;
- pool_put(ns->netns.addresses, addr);
- netns_notify(ns, addr, NETNS_TYPE_ADDR, NETNS_F_DEL);
- return 0;
- }
-
- if (!addr) {
- pool_get(ns->netns.addresses, addr);
- memset(addr, 0, sizeof(*addr));
- rtnl_entry_set(addr, rtas, ns_addrmap, 1);
- } else {
- rtnl_entry_set(addr, rtas, ns_addrmap, 0);
- }
+ if (!addr)
+ {
+ pool_get (ns->netns.addresses, addr);
+ memset (addr, 0, sizeof (*addr));
+ rtnl_entry_set (addr, rtas, ns_addrmap, 1);
+ }
+ else
+ {
+ rtnl_entry_set (addr, rtas, ns_addrmap, 0);
+ }
addr->ifaddr = *ifaddr;
- addr->last_updated = vlib_time_now(vlib_get_main());
- netns_notify(ns, addr, NETNS_TYPE_ADDR, NETNS_F_ADD);
+ addr->last_updated = vlib_time_now (vlib_get_main ());
+ netns_notify (ns, addr, NETNS_TYPE_ADDR, NETNS_F_ADD);
return 0;
}
static ns_neigh_t *
-ns_get_neigh(netns_p *ns, struct ndmsg *nd, struct rtattr *rtas[])
+ns_get_neigh (netns_p *ns, struct ndmsg *nd, struct rtattr *rtas[])
{
ns_neigh_t *neigh;
- //This describes the values which uniquely identify a route
+ // This describes the values which uniquely identify a route
struct ndmsg msg = {
.ndm_family = 0xff,
.ndm_ifindex = 0xff,
};
- pool_foreach(neigh, ns->netns.neighbors, {
- if(mask_match(&neigh->nd, nd, &msg, sizeof(&msg)) &&
- rtnl_entry_match(neigh, rtas, ns_neighmap))
- return neigh;
- });
+ pool_foreach (neigh, ns->netns.neighbors, {
+ if (mask_match (&neigh->nd, nd, &msg, sizeof (&msg)) &&
+ rtnl_entry_match (neigh, rtas, ns_neighmap))
+ return neigh;
+ })
+ ;
return NULL;
}
static int
-ns_rcv_neigh(netns_p *ns, struct nlmsghdr *hdr)
+ns_rcv_neigh (netns_p *ns, struct nlmsghdr *hdr)
{
ns_neigh_t *neigh;
struct ndmsg *nd;
struct rtattr *rtas[NDA_MAX + 1] = {};
- size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN(sizeof(*hdr));
+ size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN (sizeof (*hdr));
- if(datalen < sizeof(*nd))
+ if (datalen < sizeof (*nd))
return -1;
- nd = NLMSG_DATA(hdr);
- if((datalen > NLMSG_ALIGN(sizeof(*nd))) &&
- rtnl_parse_rtattr(rtas, NDA_MAX, NDA_RTA(nd),
- NDA_PAYLOAD(hdr))) {
- return -1;
- }
+ nd = NLMSG_DATA (hdr);
+ if ((datalen > NLMSG_ALIGN (sizeof (*nd))) &&
+ rtnl_parse_rtattr (rtas, NDA_MAX, NDA_RTA (nd), NDA_PAYLOAD (hdr)))
+ {
+ return -1;
+ }
#ifdef RTNL_CHECK
- rtnl_entry_check(rtas, NDA_MAX + 1, ns_neighmap, "nd");
+ rtnl_entry_check (rtas, NDA_MAX + 1, ns_neighmap, "nd");
#endif
- neigh = ns_get_neigh(ns, nd, rtas);
+ neigh = ns_get_neigh (ns, nd, rtas);
+
+ if (hdr->nlmsg_type == RTM_DELNEIGH)
+ {
+ if (!neigh)
+ return -1;
+ pool_put (ns->netns.neighbors, neigh);
+ netns_notify (ns, neigh, NETNS_TYPE_NEIGH, NETNS_F_DEL);
+ return 0;
+ }
- if (hdr->nlmsg_type == RTM_DELNEIGH) {
- if (!neigh)
- return -1;
- pool_put(ns->netns.neighbors, neigh);
- netns_notify(ns, neigh, NETNS_TYPE_NEIGH, NETNS_F_DEL);
- return 0;
- }
-
- if (!neigh) {
- pool_get(ns->netns.neighbors, neigh);
- memset(neigh, 0, sizeof(*neigh));
- rtnl_entry_set(neigh, rtas, ns_neighmap, 1);
- } else {
- rtnl_entry_set(neigh, rtas, ns_neighmap, 0);
- }
+ if (!neigh)
+ {
+ pool_get (ns->netns.neighbors, neigh);
+ memset (neigh, 0, sizeof (*neigh));
+ rtnl_entry_set (neigh, rtas, ns_neighmap, 1);
+ }
+ else
+ {
+ rtnl_entry_set (neigh, rtas, ns_neighmap, 0);
+ }
neigh->nd = *nd;
- neigh->last_updated = vlib_time_now(vlib_get_main());
- netns_notify(ns, neigh, NETNS_TYPE_NEIGH, NETNS_F_ADD);
+ neigh->last_updated = vlib_time_now (vlib_get_main ());
+ netns_notify (ns, neigh, NETNS_TYPE_NEIGH, NETNS_F_ADD);
return 0;
}
-#define ns_object_foreach \
- _(neighbors, NETNS_TYPE_NEIGH) \
- _(routes, NETNS_TYPE_ROUTE) \
- _(addresses, NETNS_TYPE_ADDR) \
- _(links, NETNS_TYPE_LINK)
+#define ns_object_foreach \
+ _ (neighbors, NETNS_TYPE_NEIGH) \
+ _ (routes, NETNS_TYPE_ROUTE) \
+ _ (addresses, NETNS_TYPE_ADDR) \
+ _ (links, NETNS_TYPE_LINK)
static void
-ns_recv_error(rtnl_error_t err, uword o)
+ns_recv_error (rtnl_error_t err, uword o)
{
- //An error was received. Reset everything.
+ // An error was received. Reset everything.
netns_p *ns = &netns_main.netnss[o];
u32 *indexes = 0;
u32 *i = 0;
-#define _(pool, type) \
- pool_foreach_index(*i, ns->netns.pool, { \
- vec_add1(indexes, *i); \
- }) \
- vec_foreach(i, indexes) { \
- pool_put_index(ns->netns.pool, *i); \
- netns_notify(ns, &ns->netns.pool[*i], type, NETNS_F_DEL); \
- } \
- vec_reset_length(indexes);
+#define _(pool, type) \
+ pool_foreach_index (*i, ns->netns.pool, { vec_add1 (indexes, *i); }) \
+ vec_foreach (i, indexes) \
+ { \
+ pool_put_index (ns->netns.pool, *i); \
+ netns_notify (ns, &ns->netns.pool[*i], type, NETNS_F_DEL); \
+ } \
+ vec_reset_length (indexes);
ns_object_foreach
#undef _
- vec_free(indexes);
+ vec_free (indexes);
}
static void
-ns_recv_rtnl(struct nlmsghdr *hdr, uword o)
+ns_recv_rtnl (struct nlmsghdr *hdr, uword o)
{
netns_p *ns = &netns_main.netnss[o];
- switch (hdr->nlmsg_type) {
- case RTM_NEWROUTE:
- case RTM_DELROUTE:
- ns_rcv_route(ns, hdr);
- break;
- case RTM_NEWLINK:
- case RTM_DELLINK:
- ns_rcv_link(ns, hdr);
- break;
- case RTM_NEWADDR:
- case RTM_DELADDR:
- ns_rcv_addr(ns, hdr);
- break;
- case RTM_NEWNEIGH:
- case RTM_DELNEIGH:
- ns_rcv_neigh(ns, hdr);
- break;
- default:
- clib_warning("unknown rtnl type %d", hdr->nlmsg_type);
- break;
- }
+ switch (hdr->nlmsg_type)
+ {
+ case RTM_NEWROUTE:
+ case RTM_DELROUTE:
+ ns_rcv_route (ns, hdr);
+ break;
+ case RTM_NEWLINK:
+ case RTM_DELLINK:
+ ns_rcv_link (ns, hdr);
+ break;
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ ns_rcv_addr (ns, hdr);
+ break;
+ case RTM_NEWNEIGH:
+ case RTM_DELNEIGH:
+ ns_rcv_neigh (ns, hdr);
+ break;
+ default:
+ clib_warning ("unknown rtnl type %d", hdr->nlmsg_type);
+ break;
+ }
}
static void
-netns_destroy(netns_p *ns)
+netns_destroy (netns_p *ns)
{
netns_main_t *nm = &netns_main;
- rtnl_stream_close(ns->rtnl_handle);
- pool_put(nm->netnss, ns);
- pool_free(ns->netns.links);
- pool_free(ns->netns.addresses);
- pool_free(ns->netns.routes);
- pool_free(ns->netns.neighbors);
+ rtnl_stream_close (ns->rtnl_handle);
+ pool_put (nm->netnss, ns);
+ pool_free (ns->netns.links);
+ pool_free (ns->netns.addresses);
+ pool_free (ns->netns.routes);
+ pool_free (ns->netns.neighbors);
}
static netns_p *
-netns_get(char *name)
+netns_get (char *name)
{
netns_main_t *nm = &netns_main;
netns_p *ns;
- pool_foreach(ns, nm->netnss, {
- if (!strcmp(name, ns->netns.name))
- return ns;
- });
+ pool_foreach (ns, nm->netnss, {
+ if (!strcmp (name, ns->netns.name))
+ return ns;
+ })
+ ;
- if (strlen(name) > RTNL_NETNS_NAMELEN)
+ if (strlen (name) > RTNL_NETNS_NAMELEN)
return NULL;
- pool_get(nm->netnss, ns);
+ pool_get (nm->netnss, ns);
rtnl_stream_t s = {
.recv_message = ns_recv_rtnl,
.error = ns_recv_error,
- .opaque = (uword)(ns - nm->netnss),
+ .opaque = (uword) (ns - nm->netnss),
};
- strcpy(s.name, name);
+ int rc = strcpy_s (s.name, sizeof (s.name), name);
+ if (rc != EOK)
+ return NULL;
u32 handle;
- if ((handle = rtnl_stream_open(&s)) == ~0) {
- pool_put(nm->netnss, ns);
- return NULL;
- }
+ if ((handle = rtnl_stream_open (&s)) == ~0)
+ {
+ pool_put (nm->netnss, ns);
+ return NULL;
+ }
- strcpy(ns->netns.name, name);
+ rc = strcpy_s (ns->netns.name, sizeof (ns->netns.name), name);
+ if (rc != EOK)
+ return NULL;
ns->netns.addresses = 0;
ns->netns.links = 0;
ns->netns.neighbors = 0;
@@ -691,15 +737,16 @@ netns_get(char *name)
return ns;
}
-u32 netns_open(char *name, netns_sub_t *sub)
+u32
+netns_open (char *name, netns_sub_t *sub)
{
netns_main_t *nm = &netns_main;
netns_p *ns;
netns_handle_t *p;
- if (!(ns = netns_get(name)))
+ if (!(ns = netns_get (name)))
return ~0;
- pool_get(nm->handles, p);
+ pool_get (nm->handles, p);
p->netns_index = ns - nm->netnss;
p->notify = sub->notify;
p->opaque = sub->opaque;
@@ -707,76 +754,82 @@ u32 netns_open(char *name, netns_sub_t *sub)
return p - nm->handles;
}
-netns_t *netns_getns(u32 handle)
+netns_t *
+netns_getns (u32 handle)
{
netns_main_t *nm = &netns_main;
- netns_handle_t *h = pool_elt_at_index(nm->handles, handle);
- netns_p *ns = pool_elt_at_index(nm->netnss, h->netns_index);
+ netns_handle_t *h = pool_elt_at_index (nm->handles, handle);
+ netns_p *ns = pool_elt_at_index (nm->netnss, h->netns_index);
return &ns->netns;
}
-void netns_close(u32 handle)
+void
+netns_close (u32 handle)
{
netns_main_t *nm = &netns_main;
- netns_handle_t *h = pool_elt_at_index(nm->handles, handle);
- netns_p *ns = pool_elt_at_index(nm->netnss, h->netns_index);
- pool_put(h, nm->handles);
+ netns_handle_t *h = pool_elt_at_index (nm->handles, handle);
+ netns_p *ns = pool_elt_at_index (nm->netnss, h->netns_index);
+ pool_put (h, nm->handles);
ns->subscriber_count--;
if (!ns->subscriber_count)
- netns_destroy(ns);
+ netns_destroy (ns);
}
-void netns_callme(u32 handle, char del)
+void
+netns_callme (u32 handle, char del)
{
netns_main_t *nm = &netns_main;
- netns_handle_t *h = pool_elt_at_index(nm->handles, handle);
- netns_p *ns = pool_elt_at_index(nm->netnss, h->netns_index);
+ netns_handle_t *h = pool_elt_at_index (nm->handles, handle);
+ netns_p *ns = pool_elt_at_index (nm->netnss, h->netns_index);
u32 i = 0;
if (!h->notify)
return;
-#define _(pool, type) \
- pool_foreach_index(i, ns->netns.pool, { \
- h->notify(&ns->netns.pool[i], type, \
- del?NETNS_F_DEL:NETNS_F_ADD, h->opaque); \
- });
+#define _(pool, type) \
+ pool_foreach_index (i, ns->netns.pool, { \
+ h->notify (&ns->netns.pool[i], type, del ? NETNS_F_DEL : NETNS_F_ADD, \
+ h->opaque); \
+ }) \
+ ;
ns_object_foreach
#undef _
+}
+u8 *
+format_ns_object (u8 *s, va_list *args)
+{
+ netns_type_t t = va_arg (*args, netns_type_t);
+ void *o = va_arg (*args, void *);
+ switch (t)
+ {
+ case NETNS_TYPE_ADDR:
+ return format (s, "addr %U", format_ns_addr, o);
+ case NETNS_TYPE_ROUTE:
+ return format (s, "route %U", format_ns_route, o);
+ case NETNS_TYPE_LINK:
+ return format (s, "link %U", format_ns_link, o);
+ case NETNS_TYPE_NEIGH:
+ return format (s, "neigh %U", format_ns_neigh, o);
}
-
-u8 *format_ns_object(u8 *s, va_list *args)
-{
- netns_type_t t = va_arg(*args, netns_type_t);
- void *o = va_arg(*args, void *);
- switch (t) {
- case NETNS_TYPE_ADDR:
- return format(s, "addr %U", format_ns_addr, o);
- case NETNS_TYPE_ROUTE:
- return format(s, "route %U", format_ns_route, o);
- case NETNS_TYPE_LINK:
- return format(s, "link %U", format_ns_link, o);
- case NETNS_TYPE_NEIGH:
- return format(s, "neigh %U", format_ns_neigh, o);
- }
return s;
}
-u8 *format_ns_flags(u8 *s, va_list *args)
+u8 *
+format_ns_flags (u8 *s, va_list *args)
{
- u32 flags = va_arg(*args, u32);
+ u32 flags = va_arg (*args, u32);
if (flags & NETNS_F_ADD)
- s = format(s, "add");
+ s = format (s, "add");
else if (flags & NETNS_F_DEL)
- s = format(s, "del");
+ s = format (s, "del");
else
- s = format(s, "mod");
+ s = format (s, "mod");
return s;
}
clib_error_t *
-netns_init (vlib_main_t * vm)
+netns_init (vlib_main_t *vm)
{
netns_main_t *nm = &netns_main;
nm->netnss = 0;
diff --git a/extras/router-plugin/devices/rtnetlink/netns.h b/extras/router-plugin/devices/rtnetlink/netns.h
index 53effe5ce..b94356c3b 100644
--- a/extras/router-plugin/devices/rtnetlink/netns.h
+++ b/extras/router-plugin/devices/rtnetlink/netns.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -18,10 +18,10 @@
#include <vlib/vlib.h>
-#include <sys/socket.h>
-#include <linux/rtnetlink.h>
#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
#include <net/if.h>
+#include <sys/socket.h>
#include "rtnl.h"
@@ -30,7 +30,8 @@
/*so far depth is fixed, looking into ways to be dynamic*/
#define MPLS_STACK_DEPTH 7
-typedef struct {
+typedef struct
+{
struct ifinfomsg ifi;
u8 hwaddr[IFHWADDRLEN];
u8 broadcast[IFHWADDRLEN];
@@ -38,11 +39,13 @@ typedef struct {
u32 mtu;
u32 master;
u8 qdisc[IFNAMSIZ];
- struct rtnl_link_stats stats; //This struct is big and only comes as a response to a request
+ struct rtnl_link_stats
+ stats; // This struct is big and only comes as a response to a request
f64 last_updated;
} ns_link_t;
-typedef struct {
+typedef struct
+{
struct rtmsg rtm;
u8 dst[16];
u8 src[16];
@@ -58,7 +61,8 @@ typedef struct {
f64 last_updated;
} ns_route_t;
-typedef struct {
+typedef struct
+{
struct ifaddrmsg ifaddr;
u8 addr[16];
u8 local[16];
@@ -69,7 +73,8 @@ typedef struct {
f64 last_updated;
} ns_addr_t;
-typedef struct {
+typedef struct
+{
struct ndmsg nd;
u8 dst[16];
u8 lladdr[IFHWADDRLEN];
@@ -78,28 +83,30 @@ typedef struct {
f64 last_updated;
} ns_neigh_t;
-typedef struct {
+typedef struct
+{
char name[RTNL_NETNS_NAMELEN + 1];
- ns_link_t *links;
+ ns_link_t *links;
ns_route_t *routes;
- ns_addr_t *addresses;
+ ns_addr_t *addresses;
ns_neigh_t *neighbors;
} netns_t;
-
-typedef enum {
+typedef enum
+{
NETNS_TYPE_LINK,
NETNS_TYPE_ROUTE,
NETNS_TYPE_ADDR,
NETNS_TYPE_NEIGH,
} netns_type_t;
-//Flags used in notification functions call
-#define NETNS_F_ADD 0x01
-#define NETNS_F_DEL 0x02
+// Flags used in notification functions call
+#define NETNS_F_ADD 0x01
+#define NETNS_F_DEL 0x02
-typedef struct {
- void (*notify)(void *obj, netns_type_t type, u32 flags, uword opaque);
+typedef struct
+{
+ void (*notify) (void *obj, netns_type_t type, u32 flags, uword opaque);
uword opaque;
} netns_sub_t;
@@ -110,36 +117,36 @@ typedef struct {
* existing routes (This is to protect against
* synch. Vs asynch. issues).
*/
-u32 netns_open(char *name, netns_sub_t *sub);
+u32 netns_open (char *name, netns_sub_t *sub);
/*
* Retrieves the namespace structure associated with a
* given namespace handler.
*/
-netns_t *netns_getns(u32 handle);
+netns_t *netns_getns (u32 handle);
/*
* Terminates a subscriber session.
*/
-void netns_close(u32 handle);
+void netns_close (u32 handle);
/*
* Calls the callback associated with the handle
* for all existing objects with the flags
* set to (del?NETNS_F_DEL:NETNS_F_ADD).
*/
-void netns_callme(u32 handle, char del);
+void netns_callme (u32 handle, char del);
/*
* netns struct format functions.
* Taking the struct as single argument.
*/
-u8 *format_ns_neigh(u8 *s, va_list *args);
-u8 *format_ns_addr(u8 *s, va_list *args);
-u8 *format_ns_route(u8 *s, va_list *args);
-u8 *format_ns_link(u8 *s, va_list *args);
+u8 *format_ns_neigh (u8 *s, va_list *args);
+u8 *format_ns_addr (u8 *s, va_list *args);
+u8 *format_ns_route (u8 *s, va_list *args);
+u8 *format_ns_link (u8 *s, va_list *args);
-u8 *format_ns_object(u8 *s, va_list *args);
-u8 *format_ns_flags(u8 *s, va_list *args);
+u8 *format_ns_object (u8 *s, va_list *args);
+u8 *format_ns_flags (u8 *s, va_list *args);
#endif
diff --git a/extras/router-plugin/devices/rtnetlink/rtnl.c b/extras/router-plugin/devices/rtnetlink/rtnl.c
index ed3db9e72..9c4757b17 100644
--- a/extras/router-plugin/devices/rtnetlink/rtnl.c
+++ b/extras/router-plugin/devices/rtnetlink/rtnl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -16,20 +16,20 @@
#define _GNU_SOURCE
#include <sched.h>
-#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
+#include <vlib/vlib.h>
#include <vppinfra/error.h>
-#include <sys/socket.h>
+#include <fcntl.h>
+#include <float.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
-#include <float.h>
-#include <fcntl.h>
+#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
#include <errno.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include "netns.h"
#include "rtnl.h"
@@ -37,19 +37,22 @@
#undef DBL_MAX
#define DBL_MAX 1000000000.0
-typedef enum {
+typedef enum
+{
RTNL_E_OPEN,
RTNL_E_CLOSE,
RTNL_E_READ,
} rtnl_event_t;
-typedef enum {
+typedef enum
+{
RTNL_S_INIT,
RTNL_S_SYNC,
RTNL_S_READY,
} rtnl_state_t;
-typedef enum {
+typedef enum
+{
RTNL_SS_OPENING,
RTNL_SS_LINK,
RTNL_SS_ADDR,
@@ -58,7 +61,8 @@ typedef enum {
RTNL_SS_NEIGH,
} rtnl_sync_state_t;
-typedef struct {
+typedef struct
+{
rtnl_stream_t stream;
rtnl_state_t state;
rtnl_sync_state_t sync_state;
@@ -69,7 +73,8 @@ typedef struct {
f64 timeout;
} rtnl_ns_t;
-typedef struct {
+typedef struct
+{
f64 now;
rtnl_ns_t *streams;
} rtnl_main_t;
@@ -77,204 +82,227 @@ typedef struct {
static rtnl_main_t rtnl_main;
static vlib_node_registration_t rtnl_process_node;
-#define RTNL_BUFFSIZ 16384
+#define RTNL_BUFFSIZ 16384
#define RTNL_DUMP_TIMEOUT 1
-static inline u32 grpmask(u32 g)
+static inline u32
+grpmask (u32 g)
{
ASSERT (g <= 31);
- if (g) {
- return 1 << (g - 1);
- } else
+ if (g)
+ {
+ return 1 << (g - 1);
+ }
+ else
return 0;
}
-
-u8 *format_rtnl_nsname2path(u8 *s, va_list *args)
+u8 *
+format_rtnl_nsname2path (u8 *s, va_list *args)
{
- char *nsname = va_arg(*args, char *);
- if (!nsname || !strlen(nsname)) {
- return format(s, "/proc/self/ns/net");
- } else if (strpbrk(nsname, "/") != NULL) {
- return format(s, "%s", nsname);
- } else {
- return format(s, "/var/run/netns/%s", nsname);
- }
+ char *nsname = va_arg (*args, char *);
+ if (!nsname || !strlen (nsname))
+ {
+ return format (s, "/proc/self/ns/net");
+ }
+ else if (strpbrk (nsname, "/") != NULL)
+ {
+ return format (s, "%s", nsname);
+ }
+ else
+ {
+ return format (s, "/var/run/netns/%s", nsname);
+ }
}
static_always_inline void
-rtnl_schedule_timeout(rtnl_ns_t *ns, f64 when)
+rtnl_schedule_timeout (rtnl_ns_t *ns, f64 when)
{
ns->timeout = when;
}
static_always_inline void
-rtnl_cancel_timeout(rtnl_ns_t *ns)
+rtnl_cancel_timeout (rtnl_ns_t *ns)
{
ns->timeout = DBL_MAX;
}
-static clib_error_t *rtnl_read_cb(struct clib_file * f)
+static clib_error_t *
+rtnl_read_cb (struct clib_file *f)
{
rtnl_main_t *rm = &rtnl_main;
- vlib_main_t *vm = vlib_get_main();
+ vlib_main_t *vm = vlib_get_main ();
rtnl_ns_t *ns = &rm->streams[f->private_data];
- vlib_process_signal_event(vm, rtnl_process_node.index, RTNL_E_READ, (uword)(ns - rm->streams));
+ vlib_process_signal_event (vm, rtnl_process_node.index, RTNL_E_READ,
+ (uword) (ns - rm->streams));
return 0;
}
-int rtnl_dump_request(rtnl_ns_t *ns, int type, void *req, size_t len)
+int
+rtnl_dump_request (rtnl_ns_t *ns, int type, void *req, size_t len)
{
struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
struct nlmsghdr nlh = {
- .nlmsg_len = NLMSG_LENGTH(len),
+ .nlmsg_len = NLMSG_LENGTH (len),
.nlmsg_type = type,
- .nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST,
+ .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
.nlmsg_pid = 0,
.nlmsg_seq = ++ns->rtnl_seq,
};
- struct iovec iov[2] = {
- { .iov_base = &nlh, .iov_len = sizeof(nlh) },
- { .iov_base = req, .iov_len = len }
- };
+ struct iovec iov[2] = { { .iov_base = &nlh, .iov_len = sizeof (nlh) },
+ { .iov_base = req, .iov_len = len } };
struct msghdr msg = {
.msg_name = &nladdr,
- .msg_namelen = sizeof(nladdr),
+ .msg_namelen = sizeof (nladdr),
.msg_iov = iov,
.msg_iovlen = 2,
};
- if(sendmsg(ns->rtnl_socket, &msg, 0) < 0) {
- clib_warning("sendmsg error: %s", strerror(errno));
- return -1;
- }
+ if (sendmsg (ns->rtnl_socket, &msg, 0) < 0)
+ {
+ clib_warning ("sendmsg error: %s", strerror (errno));
+ return -1;
+ }
return 0;
}
-static void rtnl_socket_close(rtnl_ns_t *ns)
+static void
+rtnl_socket_close (rtnl_ns_t *ns)
{
- clib_file_del(&file_main, &file_main.file_pool[ns->unix_index]);
- close(ns->rtnl_socket);
+ clib_file_del (&file_main, &file_main.file_pool[ns->unix_index]);
+ close (ns->rtnl_socket);
}
-struct rtnl_thread_exec {
+struct rtnl_thread_exec
+{
int fd;
- void *(*fn)(void *);
+ void *(*fn) (void *);
void *arg;
void **ret;
};
-static void *rtnl_exec_in_thread_fn(void *p)
+static void *
+rtnl_exec_in_thread_fn (void *p)
{
struct rtnl_thread_exec *ex = (struct rtnl_thread_exec *) p;
- if (setns(ex->fd, 0))
+ if (setns (ex->fd, 0))
return (void *) ((uword) (-errno));
- *ex->ret = ex->fn(ex->arg);
+ *ex->ret = ex->fn (ex->arg);
return NULL;
}
-static int rtnl_exec_in_namespace_byfd(int fd, void *(*fn)(void *), void *arg, void **ret)
+static int
+rtnl_exec_in_namespace_byfd (int fd, void *(*fn) (void *), void *arg,
+ void **ret)
{
pthread_t thread;
void *thread_ret;
- struct rtnl_thread_exec ex = {
- .fd = fd,
- .fn = fn,
- .arg = arg,
- .ret = ret
- };
- if(pthread_create(&thread, NULL, rtnl_exec_in_thread_fn, &ex))
+ struct rtnl_thread_exec ex = { .fd = fd, .fn = fn, .arg = arg, .ret = ret };
+ if (pthread_create (&thread, NULL, rtnl_exec_in_thread_fn, &ex))
return -errno;
- if(pthread_join(thread, &thread_ret))
+ if (pthread_join (thread, &thread_ret))
return -errno;
if (thread_ret)
- return (int) ((uword)thread_ret);
+ return (int) ((uword) thread_ret);
return 0;
}
-int rtnl_exec_in_namespace(u32 stream_index, void *(*fn)(void *), void *arg, void **ret)
+int
+rtnl_exec_in_namespace (u32 stream_index, void *(*fn) (void *), void *arg,
+ void **ret)
{
rtnl_main_t *rm = &rtnl_main;
- if (pool_is_free_index(rm->streams, stream_index))
+ if (pool_is_free_index (rm->streams, stream_index))
return -EBADR;
- rtnl_ns_t *ns = pool_elt_at_index(rm->streams, stream_index);
- return rtnl_exec_in_namespace_byfd(ns->ns_fd, fn, arg, ret);
+ rtnl_ns_t *ns = pool_elt_at_index (rm->streams, stream_index);
+ return rtnl_exec_in_namespace_byfd (ns->ns_fd, fn, arg, ret);
}
-int rtnl_exec_in_namespace_by_name(char *nsname, void *(*fn)(void *), void *arg, void **ret)
+int
+rtnl_exec_in_namespace_by_name (char *nsname, void *(*fn) (void *), void *arg,
+ void **ret)
{
int fd;
- u8 *s = format((u8 *)0, "%U", format_rtnl_nsname2path, nsname);
+ u8 *s = format ((u8 *) 0, "%U", format_rtnl_nsname2path, nsname);
- if ((fd = open((char *)s, O_RDONLY)) < 0) {
- vec_free(s);
- return -errno;
- }
+ if ((fd = open ((char *) s, O_RDONLY)) < 0)
+ {
+ vec_free (s);
+ return -errno;
+ }
- int r = rtnl_exec_in_namespace_byfd(fd, fn, arg, ret);
- vec_free(s);
- close(fd);
+ int r = rtnl_exec_in_namespace_byfd (fd, fn, arg, ret);
+ vec_free (s);
+ close (fd);
return r;
}
/* this function is run by the second thread */
-static void *rtnl_thread_fn(void *p)
+static void *
+rtnl_thread_fn (void *p)
{
rtnl_ns_t *ns = (rtnl_ns_t *) p;
- if (setns(ns->ns_fd, 0)) {
- clib_warning("setns(%d, %d) error %d", ns->ns_fd, CLONE_NEWNET, errno);
- return (void *) -1;
- }
+ if (setns (ns->ns_fd, 0))
+ {
+ clib_warning ("setns(%d, %d) error %d", ns->ns_fd, CLONE_NEWNET, errno);
+ return (void *) -1;
+ }
- if ((ns->rtnl_socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
- clib_warning("Cannot open socket");
- return (void *) -2;
- }
+ if ((ns->rtnl_socket = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
+ {
+ clib_warning ("Cannot open socket");
+ return (void *) -2;
+ }
return NULL;
}
-static int rtnl_socket_open(rtnl_ns_t *ns)
+static int
+rtnl_socket_open (rtnl_ns_t *ns)
{
rtnl_main_t *rm = &rtnl_main;
pthread_t thread;
void *thread_ret;
- if(pthread_create(&thread, NULL, rtnl_thread_fn, ns)) {
- clib_warning("Can't create opening thread");
- return -1;
- }
+ if (pthread_create (&thread, NULL, rtnl_thread_fn, ns))
+ {
+ clib_warning ("Can't create opening thread");
+ return -1;
+ }
- if(pthread_join(thread, &thread_ret)) {
- clib_warning("Can't join opening thread");
- return -2;
- }
+ if (pthread_join (thread, &thread_ret))
+ {
+ clib_warning ("Can't join opening thread");
+ return -2;
+ }
- if (thread_ret) {
- clib_warning("Could not open netlink socket");
- return -3;
- }
+ if (thread_ret)
+ {
+ clib_warning ("Could not open netlink socket");
+ return -3;
+ }
struct sockaddr_nl addr = {
.nl_family = AF_NETLINK,
.nl_pad = 0,
.nl_pid = 0,
/*add mpls message group*/
- .nl_groups = grpmask(RTNLGRP_LINK)| grpmask(RTNLGRP_IPV6_IFADDR) |
- grpmask(RTNLGRP_IPV4_IFADDR) | grpmask(RTNLGRP_IPV4_ROUTE) |
- grpmask(RTNLGRP_IPV6_ROUTE) | grpmask(RTNLGRP_NEIGH) |
- grpmask(RTNLGRP_NOTIFY) /* | grpmask(RTNLGRP_MPLS_ROUTE)*/,
+ .nl_groups = grpmask (RTNLGRP_LINK) | grpmask (RTNLGRP_IPV6_IFADDR) |
+ grpmask (RTNLGRP_IPV4_IFADDR) | grpmask (RTNLGRP_IPV4_ROUTE) |
+ grpmask (RTNLGRP_IPV6_ROUTE) | grpmask (RTNLGRP_NEIGH) |
+ grpmask (RTNLGRP_NOTIFY) /* | grpmask(RTNLGRP_MPLS_ROUTE)*/,
};
- if (bind(ns->rtnl_socket, (struct sockaddr*) &addr, sizeof(addr))) {
- close(ns->rtnl_socket);
- return -3;
- }
+ if (bind (ns->rtnl_socket, (struct sockaddr *) &addr, sizeof (addr)))
+ {
+ close (ns->rtnl_socket);
+ return -3;
+ }
- clib_file_t template = {0};
+ clib_file_t template = { 0 };
template.read_function = rtnl_read_cb;
template.file_descriptor = ns->rtnl_socket;
template.private_data = (uword) (ns - rm->streams);
@@ -283,11 +311,11 @@ static int rtnl_socket_open(rtnl_ns_t *ns)
}
static int
-rtnl_rcv_error(rtnl_ns_t *ns, struct nlmsghdr *hdr, int *error)
+rtnl_rcv_error (rtnl_ns_t *ns, struct nlmsghdr *hdr, int *error)
{
- struct nlmsgerr *err = NLMSG_DATA(hdr);
- size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN(sizeof(*hdr));
- if(datalen < sizeof(*err))
+ struct nlmsgerr *err = NLMSG_DATA (hdr);
+ size_t datalen = hdr->nlmsg_len - NLMSG_ALIGN (sizeof (*hdr));
+ if (datalen < sizeof (*err))
return -1;
*error = err->error;
@@ -295,142 +323,152 @@ rtnl_rcv_error(rtnl_ns_t *ns, struct nlmsghdr *hdr, int *error)
}
static void
-rtnl_sync_reset(rtnl_ns_t *ns)
+rtnl_sync_reset (rtnl_ns_t *ns)
{
if (ns->sync_state == RTNL_SS_OPENING)
return;
- rtnl_socket_close(ns);
+ rtnl_socket_close (ns);
ns->sync_state = RTNL_SS_OPENING;
}
static void
-rtnl_sync_done(rtnl_ns_t *ns)
+rtnl_sync_done (rtnl_ns_t *ns)
{
rtnl_main_t *rm = &rtnl_main;
struct ifaddrmsg addrmsg;
struct rtmsg rtmsg;
struct ndmsg ndmsg;
- switch (ns->sync_state) {
- case RTNL_SS_OPENING:
- //Cannot happen here
- break;
- case RTNL_SS_LINK:
- memset(&addrmsg, 0, sizeof(addrmsg));
- addrmsg.ifa_family = AF_UNSPEC;
- if(rtnl_dump_request(ns, RTM_GETADDR, &addrmsg, sizeof(addrmsg))) {
- rtnl_sync_reset(ns);
- rtnl_schedule_timeout(ns, rm->now + 1);
- return;
- }
- rtnl_schedule_timeout(ns, rm->now + RTNL_DUMP_TIMEOUT);
- ns->sync_state = RTNL_SS_ADDR;
- break;
- case RTNL_SS_ADDR:
- case RTNL_SS_ROUTE4:
- memset(&rtmsg, 0, sizeof(rtmsg));
- rtmsg.rtm_family = (ns->sync_state == RTNL_SS_ADDR)?AF_INET:AF_INET6;
- rtmsg.rtm_table = RT_TABLE_UNSPEC;
- if(rtnl_dump_request(ns, RTM_GETROUTE, &rtmsg, sizeof(rtmsg))) {
- rtnl_sync_reset(ns);
- rtnl_schedule_timeout(ns, rm->now + 1);
- return;
+ switch (ns->sync_state)
+ {
+ case RTNL_SS_OPENING:
+ // Cannot happen here
+ break;
+ case RTNL_SS_LINK:
+ memset (&addrmsg, 0, sizeof (addrmsg));
+ addrmsg.ifa_family = AF_UNSPEC;
+ if (rtnl_dump_request (ns, RTM_GETADDR, &addrmsg, sizeof (addrmsg)))
+ {
+ rtnl_sync_reset (ns);
+ rtnl_schedule_timeout (ns, rm->now + 1);
+ return;
+ }
+ rtnl_schedule_timeout (ns, rm->now + RTNL_DUMP_TIMEOUT);
+ ns->sync_state = RTNL_SS_ADDR;
+ break;
+ case RTNL_SS_ADDR:
+ case RTNL_SS_ROUTE4:
+ memset (&rtmsg, 0, sizeof (rtmsg));
+ rtmsg.rtm_family = (ns->sync_state == RTNL_SS_ADDR) ? AF_INET : AF_INET6;
+ rtmsg.rtm_table = RT_TABLE_UNSPEC;
+ if (rtnl_dump_request (ns, RTM_GETROUTE, &rtmsg, sizeof (rtmsg)))
+ {
+ rtnl_sync_reset (ns);
+ rtnl_schedule_timeout (ns, rm->now + 1);
+ return;
+ }
+ rtnl_schedule_timeout (ns, rm->now + RTNL_DUMP_TIMEOUT);
+ ns->sync_state =
+ (ns->sync_state == RTNL_SS_ADDR) ? RTNL_SS_ROUTE4 : RTNL_SS_ROUTE6;
+ break;
+ case RTNL_SS_ROUTE6:
+ memset (&ndmsg, 0, sizeof (ndmsg));
+ ndmsg.ndm_family = AF_UNSPEC;
+ if (rtnl_dump_request (ns, RTM_GETNEIGH, &ndmsg, sizeof (ndmsg)))
+ {
+ rtnl_sync_reset (ns);
+ rtnl_schedule_timeout (ns, rm->now + 1);
+ return;
+ }
+ rtnl_schedule_timeout (ns, rm->now + RTNL_DUMP_TIMEOUT);
+ ns->sync_state = RTNL_SS_NEIGH;
+ break;
+ case RTNL_SS_NEIGH:
+ ns->state = RTNL_S_READY;
+ ns->sync_state = 0;
+ rtnl_cancel_timeout (ns);
+ break;
}
- rtnl_schedule_timeout(ns, rm->now + RTNL_DUMP_TIMEOUT);
- ns->sync_state = (ns->sync_state == RTNL_SS_ADDR)?RTNL_SS_ROUTE4:RTNL_SS_ROUTE6;
- break;
- case RTNL_SS_ROUTE6:
- memset(&ndmsg, 0, sizeof(ndmsg));
- ndmsg.ndm_family = AF_UNSPEC;
- if(rtnl_dump_request(ns, RTM_GETNEIGH, &ndmsg, sizeof(ndmsg))) {
- rtnl_sync_reset(ns);
- rtnl_schedule_timeout(ns, rm->now + 1);
- return;
- }
- rtnl_schedule_timeout(ns, rm->now + RTNL_DUMP_TIMEOUT);
- ns->sync_state = RTNL_SS_NEIGH;
- break;
- case RTNL_SS_NEIGH:
- ns->state = RTNL_S_READY;
- ns->sync_state = 0;
- rtnl_cancel_timeout(ns);
- break;
- }
}
static void
-rtnl_sync_timeout(rtnl_ns_t *ns)
+rtnl_sync_timeout (rtnl_ns_t *ns)
{
rtnl_main_t *rm = &rtnl_main;
struct ifinfomsg imsg = {};
- switch (ns->sync_state) {
- case RTNL_SS_OPENING:
- if (rtnl_socket_open(ns)) {
- rtnl_schedule_timeout(ns, rm->now + 10);
- return;
- }
- imsg.ifi_family = AF_UNSPEC;
- if (rtnl_dump_request(ns, RTM_GETLINK, &imsg, sizeof(imsg))) {
- rtnl_sync_reset(ns);
- rtnl_schedule_timeout(ns, rm->now + 10);
+ switch (ns->sync_state)
+ {
+ case RTNL_SS_OPENING:
+ if (rtnl_socket_open (ns))
+ {
+ rtnl_schedule_timeout (ns, rm->now + 10);
+ return;
+ }
+ imsg.ifi_family = AF_UNSPEC;
+ if (rtnl_dump_request (ns, RTM_GETLINK, &imsg, sizeof (imsg)))
+ {
+ rtnl_sync_reset (ns);
+ rtnl_schedule_timeout (ns, rm->now + 10);
+ }
+ ns->sync_state = RTNL_SS_LINK;
+ rtnl_schedule_timeout (ns, rm->now + 2);
+ break;
+ case RTNL_SS_LINK:
+ case RTNL_SS_ADDR:
+ case RTNL_SS_ROUTE4:
+ case RTNL_SS_ROUTE6:
+ case RTNL_SS_NEIGH:
+ // Timeout happened while synchronizing
+ rtnl_sync_reset (ns);
+ rtnl_schedule_timeout (ns, rm->now + 1);
+ break;
}
- ns->sync_state = RTNL_SS_LINK;
- rtnl_schedule_timeout(ns, rm->now + 2);
- break;
- case RTNL_SS_LINK:
- case RTNL_SS_ADDR:
- case RTNL_SS_ROUTE4:
- case RTNL_SS_ROUTE6:
- case RTNL_SS_NEIGH:
- //Timeout happened while synchronizing
- rtnl_sync_reset(ns);
- rtnl_schedule_timeout(ns, rm->now + 1);
- break;
- }
}
static int
-rtnl_ns_recv(rtnl_ns_t *ns, struct nlmsghdr *hdr)
+rtnl_ns_recv (rtnl_ns_t *ns, struct nlmsghdr *hdr)
{
rtnl_main_t *rm = &rtnl_main;
int ret, error = 0;
- if (ns->state == RTNL_S_SYNC &&
- ((hdr->nlmsg_flags & RTM_F_NOTIFY) ||
- (hdr->nlmsg_seq != (ns->rtnl_seq)))) {
- clib_warning("Received notification while in sync. Restart synchronization.");
- rtnl_sync_reset(ns);
- rtnl_schedule_timeout(ns, rm->now);
- }
-
- switch (hdr->nlmsg_type) {
- case NLMSG_DONE:
- rtnl_sync_done(ns);
- break;
- case NLMSG_ERROR:
- if((ret = rtnl_rcv_error(ns, hdr, &error)))
- return ret;
- break;
- case RTM_NEWROUTE:
- case RTM_DELROUTE:
- case RTM_NEWLINK:
- case RTM_DELLINK:
- case RTM_NEWADDR:
- case RTM_DELADDR:
- case RTM_NEWNEIGH:
- case RTM_DELNEIGH:
- if (ns->stream.recv_message)
- ns->stream.recv_message(hdr, ns->stream.opaque);
- break;
- default:
- clib_warning("Unknown rtnetlink type %d", hdr->nlmsg_type);
- break;
- }
+ if (ns->state == RTNL_S_SYNC && ((hdr->nlmsg_flags & RTM_F_NOTIFY) ||
+ (hdr->nlmsg_seq != (ns->rtnl_seq))))
+ {
+ clib_warning (
+ "Received notification while in sync. Restart synchronization.");
+ rtnl_sync_reset (ns);
+ rtnl_schedule_timeout (ns, rm->now);
+ }
+
+ switch (hdr->nlmsg_type)
+ {
+ case NLMSG_DONE:
+ rtnl_sync_done (ns);
+ break;
+ case NLMSG_ERROR:
+ if ((ret = rtnl_rcv_error (ns, hdr, &error)))
+ return ret;
+ break;
+ case RTM_NEWROUTE:
+ case RTM_DELROUTE:
+ case RTM_NEWLINK:
+ case RTM_DELLINK:
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ case RTM_NEWNEIGH:
+ case RTM_DELNEIGH:
+ if (ns->stream.recv_message)
+ ns->stream.recv_message (hdr, ns->stream.opaque);
+ break;
+ default:
+ clib_warning ("Unknown rtnetlink type %d", hdr->nlmsg_type);
+ break;
+ }
return 0;
}
static void
-rtnl_process_open(rtnl_ns_t *ns)
+rtnl_process_open (rtnl_ns_t *ns)
{
rtnl_main_t *rm = &rtnl_main;
if (ns->state != RTNL_S_INIT)
@@ -438,163 +476,182 @@ rtnl_process_open(rtnl_ns_t *ns)
ns->state = RTNL_S_SYNC;
ns->sync_state = RTNL_SS_OPENING;
- rtnl_schedule_timeout(ns, rm->now);
+ rtnl_schedule_timeout (ns, rm->now);
}
static void
-rtnl_process_close(rtnl_ns_t *ns)
+rtnl_process_close (rtnl_ns_t *ns)
{
rtnl_main_t *rm = &rtnl_main;
if (ns->state == RTNL_S_INIT)
return;
- rtnl_socket_close(ns);
- close(ns->ns_fd);
- pool_put(rm->streams, ns);
+ rtnl_socket_close (ns);
+ close (ns->ns_fd);
+ pool_put (rm->streams, ns);
}
static int
-rtnl_process_read(rtnl_ns_t *ns)
+rtnl_process_read (rtnl_ns_t *ns)
{
uint8_t buff[RTNL_BUFFSIZ];
ssize_t len;
struct nlmsghdr *hdr;
- while(1) {
- if((len = recv(ns->rtnl_socket, buff, RTNL_BUFFSIZ, MSG_DONTWAIT)) < 0) {
- if(errno != EAGAIN) {
- clib_warning("rtnetlink recv error (%d) [%s]: %s", ns->rtnl_socket, ns->stream.name, strerror(errno));
- return -1;
- }
- return 0;
- }
-
- for(hdr = (struct nlmsghdr *) buff;
- len > 0;
- len -= NLMSG_ALIGN(hdr->nlmsg_len),
- hdr = (struct nlmsghdr *) (((uint8_t *) hdr) + NLMSG_ALIGN(hdr->nlmsg_len))) {
- if((sizeof(*hdr) > (size_t)len) || (hdr->nlmsg_len > (size_t)len)) {
- clib_warning("rtnetlink buffer too small (%d Vs %d)", (int) hdr->nlmsg_len, (int) len);
- return -1;
- }
- if (rtnl_ns_recv(ns, hdr))
- return -1;
+ while (1)
+ {
+ if ((len = recv (ns->rtnl_socket, buff, RTNL_BUFFSIZ, MSG_DONTWAIT)) < 0)
+ {
+ if (errno != EAGAIN)
+ {
+ clib_warning ("rtnetlink recv error (%d) [%s]: %s",
+ ns->rtnl_socket, ns->stream.name,
+ strerror (errno));
+ return -1;
+ }
+ return 0;
+ }
+
+ for (hdr = (struct nlmsghdr *) buff; len > 0;
+ len -= NLMSG_ALIGN (hdr->nlmsg_len),
+ hdr = (struct nlmsghdr *) (((uint8_t *) hdr) +
+ NLMSG_ALIGN (hdr->nlmsg_len)))
+ {
+ if ((sizeof (*hdr) > (size_t) len) ||
+ (hdr->nlmsg_len > (size_t) len))
+ {
+ clib_warning ("rtnetlink buffer too small (%d Vs %d)",
+ (int) hdr->nlmsg_len, (int) len);
+ return -1;
+ }
+ if (rtnl_ns_recv (ns, hdr))
+ return -1;
+ }
}
- }
return 0;
}
static void
-rtnl_process_timeout(rtnl_ns_t *ns)
-{
- switch (ns->state) {
- case RTNL_S_SYNC:
- rtnl_sync_timeout(ns);
- break;
- case RTNL_S_INIT:
- case RTNL_S_READY:
- clib_warning("Should not happen");
- break;
- }
+rtnl_process_timeout (rtnl_ns_t *ns)
+{
+ switch (ns->state)
+ {
+ case RTNL_S_SYNC:
+ rtnl_sync_timeout (ns);
+ break;
+ case RTNL_S_INIT:
+ case RTNL_S_READY:
+ clib_warning ("Should not happen");
+ break;
+ }
}
static uword
-rtnl_process (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+rtnl_process (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
rtnl_main_t *rm = &rtnl_main;
uword event_type;
uword *event_data = 0;
- rm->now = vlib_time_now(vm);
+ rm->now = vlib_time_now (vm);
f64 timeout = DBL_MAX;
rtnl_ns_t *ns;
- //Setting up
- while (1) {
- vlib_process_wait_for_event_or_clock(vm, timeout - rm->now);
- event_type = vlib_process_get_events(vm, &event_data);
- rm->now = vlib_time_now(vm);
-
- if (event_type == ~0) { //Clock event or no event
- pool_foreach(ns, rm->streams, {
- if (ns->timeout < rm->now) {
- ns->timeout = DBL_MAX;
- rtnl_process_timeout(ns);
- }
- });
- } else {
- rtnl_ns_t *ns;
- uword *d;
- vec_foreach(d, event_data) {
- ns = &rm->streams[d[0]];
- switch (event_type)
- {
- case RTNL_E_CLOSE:
- rtnl_process_close(ns);
- break;
- case RTNL_E_OPEN:
- rtnl_process_open(ns);
- break;
- case RTNL_E_READ:
- rtnl_process_read(ns);
- break;
- }
- }
+ // Setting up
+ while (1)
+ {
+ vlib_process_wait_for_event_or_clock (vm, timeout - rm->now);
+ event_type = vlib_process_get_events (vm, &event_data);
+ rm->now = vlib_time_now (vm);
+
+ if (event_type == ~0)
+ { // Clock event or no event
+ pool_foreach (ns, rm->streams, {
+ if (ns->timeout < rm->now)
+ {
+ ns->timeout = DBL_MAX;
+ rtnl_process_timeout (ns);
+ }
+ })
+ ;
+ }
+ else
+ {
+ rtnl_ns_t *ns;
+ uword *d;
+ vec_foreach (d, event_data)
+ {
+ ns = &rm->streams[d[0]];
+ switch (event_type)
+ {
+ case RTNL_E_CLOSE:
+ rtnl_process_close (ns);
+ break;
+ case RTNL_E_OPEN:
+ rtnl_process_open (ns);
+ break;
+ case RTNL_E_READ:
+ rtnl_process_read (ns);
+ break;
+ }
+ }
+ }
+
+ vec_reset_length (event_data);
+
+ timeout = DBL_MAX;
+ pool_foreach (ns, rm->streams, {
+ if (ns->timeout < timeout)
+ timeout = ns->timeout;
+ })
+ ;
}
-
- vec_reset_length (event_data);
-
- timeout = DBL_MAX;
- pool_foreach(ns, rm->streams, {
- if (ns->timeout < timeout)
- timeout = ns->timeout;
- });
- }
return frame->n_vectors;
}
-VLIB_REGISTER_NODE(rtnl_process_node, static) = {
+VLIB_REGISTER_NODE (rtnl_process_node, static) = {
.function = rtnl_process,
.name = "rtnl-process",
.type = VLIB_NODE_TYPE_PROCESS,
};
u32
-rtnl_stream_open(rtnl_stream_t *template)
+rtnl_stream_open (rtnl_stream_t *template)
{
- vlib_main_t *vm = vlib_get_main();
+ vlib_main_t *vm = vlib_get_main ();
rtnl_main_t *rm = &rtnl_main;
rtnl_ns_t *ns;
int fd;
- u8 *s = format((u8 *)0, "%U", format_rtnl_nsname2path, template->name);
- vec_add1(s, 0);
-
- if ((fd = open((char *)s, O_RDONLY)) < 0) {
- clib_unix_warning("open stream %s: ", s);
- vec_free(s);
- return ~0;
- }
+ u8 *s = format ((u8 *) 0, "%U", format_rtnl_nsname2path, template->name);
+ vec_add1 (s, 0);
+
+ if ((fd = open ((char *) s, O_RDONLY)) < 0)
+ {
+ clib_unix_warning ("open stream %s: ", s);
+ vec_free (s);
+ return ~0;
+ }
- vec_free(s);
- pool_get(rm->streams, ns);
+ vec_free (s);
+ pool_get (rm->streams, ns);
ns->state = RTNL_S_INIT;
ns->ns_fd = fd;
ns->stream = *template;
- vlib_process_signal_event(vm, rtnl_process_node.index, RTNL_E_OPEN, (uword)(ns - rm->streams));
+ vlib_process_signal_event (vm, rtnl_process_node.index, RTNL_E_OPEN,
+ (uword) (ns - rm->streams));
return ns - rm->streams;
}
void
-rtnl_stream_close(u32 stream_index)
+rtnl_stream_close (u32 stream_index)
{
- vlib_main_t *vm = vlib_get_main();
+ vlib_main_t *vm = vlib_get_main ();
rtnl_main_t *rm = &rtnl_main;
- ASSERT(!pool_is_free_index(rm->streams, stream_index));
- vlib_process_signal_event(vm, rtnl_process_node.index, RTNL_E_CLOSE, stream_index);
+ ASSERT (!pool_is_free_index (rm->streams, stream_index));
+ vlib_process_signal_event (vm, rtnl_process_node.index, RTNL_E_CLOSE,
+ stream_index);
}
clib_error_t *
-rtnl_init (vlib_main_t * vm)
+rtnl_init (vlib_main_t *vm)
{
rtnl_main_t *rm = &rtnl_main;
rm->streams = 0;
diff --git a/extras/router-plugin/devices/rtnetlink/rtnl.h b/extras/router-plugin/devices/rtnetlink/rtnl.h
index 3f96252c1..4c22b912a 100644
--- a/extras/router-plugin/devices/rtnetlink/rtnl.h
+++ b/extras/router-plugin/devices/rtnetlink/rtnl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -21,7 +21,8 @@
#include <linux/netlink.h>
#include <vppinfra/clib.h>
-typedef enum {
+typedef enum
+{
RTNL_ERR_UNKNOWN,
} rtnl_error_t;
@@ -37,24 +38,27 @@ typedef enum {
* new dump requests are sent.
*/
-typedef struct rtnl_stream_s {
+typedef struct rtnl_stream_s
+{
char name[RTNL_NETNS_NAMELEN + 1];
- void (*recv_message)(struct nlmsghdr *hdr, uword opaque);
- void (*error)(rtnl_error_t err, uword opaque);
+ void (*recv_message) (struct nlmsghdr *hdr, uword opaque);
+ void (*error) (rtnl_error_t err, uword opaque);
uword opaque;
} rtnl_stream_t;
-u32 rtnl_stream_open(rtnl_stream_t *template);
-void rtnl_stream_close(u32 handle);
+u32 rtnl_stream_open (rtnl_stream_t *template);
+void rtnl_stream_close (u32 handle);
/*
* Executes a function in a synchronously executed thread in the
* given namespace.
* Returns 0 on success, and -errno on error.
*/
-int rtnl_exec_in_namespace(u32 handle, void *(*fn)(void *), void *arg, void **ret);
-int rtnl_exec_in_namespace_by_name(char *nsname, void *(*fn)(void *), void *arg, void **ret);
+int rtnl_exec_in_namespace (u32 handle, void *(*fn) (void *), void *arg,
+ void **ret);
+int rtnl_exec_in_namespace_by_name (char *nsname, void *(*fn) (void *),
+ void *arg, void **ret);
-u8 *format_rtnl_nsname2path(u8 *s, va_list *args);
+u8 *format_rtnl_nsname2path (u8 *s, va_list *args);
#endif
diff --git a/extras/router-plugin/devices/rtnetlink/test.c b/extras/router-plugin/devices/rtnetlink/test.c
index 031748dd3..c969f6108 100644
--- a/extras/router-plugin/devices/rtnetlink/test.c
+++ b/extras/router-plugin/devices/rtnetlink/test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -15,183 +15,191 @@
#include <librtnl/netns.h>
-#include <vnet/plugin/plugin.h>
#include <librtnl/mapper.h>
-#include <vnet/ip/ip.h>
#include <vnet/fib/fib.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/ip6_fib.h>
+#include <vnet/ip/ip.h>
+#include <vnet/plugin/plugin.h>
u32 handles[10];
static void
-test_notify(void *obj, netns_type_t type, u32 flags, uword opaque) {
+test_notify (void *obj, netns_type_t type, u32 flags, uword opaque)
+{
u32 index = (u32) opaque;
- const char *action = (flags & NETNS_F_ADD)?"add":(flags & NETNS_F_DEL)?"del":"mod";
+ const char *action = (flags & NETNS_F_ADD) ? "add" :
+ (flags & NETNS_F_DEL) ? "del" :
+ "mod";
- switch (type) {
+ switch (type)
+ {
case NETNS_TYPE_ADDR:
- clib_warning("%d: addr %s %U", index, action, format_ns_addr, (ns_addr_t *)obj);
+ clib_warning ("%d: addr %s %U", index, action, format_ns_addr,
+ (ns_addr_t *) obj);
break;
case NETNS_TYPE_ROUTE:
- clib_warning("%d: route %s %U", index, action, format_ns_route, (ns_route_t *)obj);
+ clib_warning ("%d: route %s %U", index, action, format_ns_route,
+ (ns_route_t *) obj);
break;
case NETNS_TYPE_LINK:
- clib_warning("%d:link %s %U", index, action, format_ns_link, (ns_link_t *)obj);
+ clib_warning ("%d:link %s %U", index, action, format_ns_link,
+ (ns_link_t *) obj);
break;
case NETNS_TYPE_NEIGH:
- clib_warning("%d: neigh %s %U", index, action, format_ns_neigh, (ns_neigh_t *)obj);
+ clib_warning ("%d: neigh %s %U", index, action, format_ns_neigh,
+ (ns_neigh_t *) obj);
break;
- }
+ }
}
static clib_error_t *
-test_enable_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
+test_enable_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
{
char *nsname = 0;
u32 index;
- if (!unformat(input, "%s", &nsname)) {
- return clib_error_return(0, "unknown input `%U'",
- format_unformat_error, input);
- }
- if (!unformat(input, "%d", &index)) {
- return clib_error_return(0, "unknown input `%U'",
- format_unformat_error, input);
- }
-
- if (!strcmp(nsname, "default"))
+ if (!unformat (input, "%s", &nsname))
+ {
+ return clib_error_return (0, "unknown input `%U'", format_unformat_error,
+ input);
+ }
+ if (!unformat (input, "%d", &index))
+ {
+ return clib_error_return (0, "unknown input `%U'", format_unformat_error,
+ input);
+ }
+
+ if (!strcmp (nsname, "default"))
nsname[0] = 0;
netns_sub_t sub;
sub.notify = test_notify;
sub.opaque = index;
- handles[index] = netns_open(nsname, &sub);
- if (handles[index] == ~0) {
- return clib_error_create("Could not open netns with name %s", nsname);
- }
+ handles[index] = netns_open (nsname, &sub);
+ if (handles[index] == ~0)
+ {
+ return clib_error_create ("Could not open netns with name %s", nsname);
+ }
return 0;
}
static clib_error_t *
-test_disable_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
+test_disable_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
{
u32 index;
- if (!unformat(input, "%d", &index)) {
- return clib_error_return(0, "unknown input `%U'",
- format_unformat_error, input);
- }
+ if (!unformat (input, "%d", &index))
+ {
+ return clib_error_return (0, "unknown input `%U'", format_unformat_error,
+ input);
+ }
- netns_close(handles[index]);
+ netns_close (handles[index]);
return 0;
}
VLIB_CLI_COMMAND (rtnl_enable_command, static) = {
- .path = "test netns enable",
- .short_help = "test netns enable [<ns-name>|default] <index>",
- .function = test_enable_command_fn,
+ .path = "test netns enable",
+ .short_help = "test netns enable [<ns-name>|default] <index>",
+ .function = test_enable_command_fn,
};
VLIB_CLI_COMMAND (rtnl_disable_command, static) = {
- .path = "test netns disable",
- .short_help = "test rtnl disable <index>",
- .function = test_disable_command_fn,
+ .path = "test netns disable",
+ .short_help = "test rtnl disable <index>",
+ .function = test_disable_command_fn,
};
u32 mapper_indexes[10];
static clib_error_t *
-mapper_ns_add_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
+mapper_ns_add_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
{
u32 index;
char *nsname;
u32 table_id;
- if (!unformat(input, "%d", &index))
- return clib_error_return(0, "invalid index `%U'",
- format_unformat_error, input);
- if (!unformat(input, "%s", &nsname))
- return clib_error_return(0, "invalid nsname `%U'",
- format_unformat_error, input);
- if (!unformat(input, "%d", &table_id))
- return clib_error_return(0, "invalid fib index `%U'",
- format_unformat_error, input);
-
- if (!strcmp(nsname, "default"))
+ if (!unformat (input, "%d", &index))
+ return clib_error_return (0, "invalid index `%U'", format_unformat_error,
+ input);
+ if (!unformat (input, "%s", &nsname))
+ return clib_error_return (0, "invalid nsname `%U'", format_unformat_error,
+ input);
+ if (!unformat (input, "%d", &table_id))
+ return clib_error_return (0, "invalid fib index `%U'",
+ format_unformat_error, input);
+
+ if (!strcmp (nsname, "default"))
nsname[0] = 0;
- u32 fib4 = ip4_fib_index_from_table_id(table_id);
- u32 fib6 = ip6_fib_index_from_table_id(table_id);
+ u32 fib4 = ip4_fib_index_from_table_id (table_id);
+ u32 fib6 = ip6_fib_index_from_table_id (table_id);
- if (mapper_add_ns(nsname, fib4, fib6, &mapper_indexes[index]))
- return clib_error_return(0, "Could not add ns %s", nsname);
+ if (mapper_add_ns (nsname, fib4, fib6, &mapper_indexes[index]))
+ return clib_error_return (0, "Could not add ns %s", nsname);
return 0;
}
VLIB_CLI_COMMAND (mapper_ns_add_command, static) = {
- .path = "test mapper ns add",
- .short_help = "test mapper ns add <index> <nsname> <table-id>",
- .function = mapper_ns_add_command_fn,
+ .path = "test mapper ns add",
+ .short_help = "test mapper ns add <index> <nsname> <table-id>",
+ .function = mapper_ns_add_command_fn,
};
static clib_error_t *
-mapper_ns_del_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
+mapper_ns_del_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
{
u32 index;
- if (!unformat(input, "%d", &index))
- return clib_error_return(0, "invalid index `%U'",
- format_unformat_error, input);
+ if (!unformat (input, "%d", &index))
+ return clib_error_return (0, "invalid index `%U'", format_unformat_error,
+ input);
- if (mapper_del_ns(mapper_indexes[index]))
- return clib_error_return(0, "Could not del ns %d", index);
+ if (mapper_del_ns (mapper_indexes[index]))
+ return clib_error_return (0, "Could not del ns %d", index);
return 0;
}
VLIB_CLI_COMMAND (mapper_ns_del_command, static) = {
- .path = "test mapper ns delete",
- .short_help = "test mapper ns delete <index>",
- .function = mapper_ns_del_command_fn,
+ .path = "test mapper ns delete",
+ .short_help = "test mapper ns delete <index>",
+ .function = mapper_ns_del_command_fn,
};
static clib_error_t *
-mapper_iface_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
+mapper_iface_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
{
u32 nsindex;
u32 ifindex;
u32 sw_if_index;
int del = 0;
- if (!unformat(input, "%d", &nsindex))
- return clib_error_return(0, "invalid nsindex `%U'",
- format_unformat_error, input);
- if (!unformat(input, "%d", &ifindex))
- return clib_error_return(0, "invalid ifindex `%U'",
- format_unformat_error, input);
- if (!unformat(input, "%d", &sw_if_index))
- return clib_error_return(0, "invalid sw_if_index `%U'",
- format_unformat_error, input);
- if (unformat(input, "del"))
+ if (!unformat (input, "%d", &nsindex))
+ return clib_error_return (0, "invalid nsindex `%U'", format_unformat_error,
+ input);
+ if (!unformat (input, "%d", &ifindex))
+ return clib_error_return (0, "invalid ifindex `%U'", format_unformat_error,
+ input);
+ if (!unformat (input, "%d", &sw_if_index))
+ return clib_error_return (0, "invalid sw_if_index `%U'",
+ format_unformat_error, input);
+ if (unformat (input, "del"))
del = 1;
- clib_warning("mapper_add_del %d %d %d %d", mapper_indexes[nsindex], ifindex, sw_if_index, del);
+ clib_warning ("mapper_add_del %d %d %d %d", mapper_indexes[nsindex], ifindex,
+ sw_if_index, del);
- if (mapper_add_del(mapper_indexes[nsindex], ifindex, sw_if_index, del))
- return clib_error_return(0, "Could not add iface");
+ if (mapper_add_del (mapper_indexes[nsindex], ifindex, sw_if_index, del))
+ return clib_error_return (0, "Could not add iface");
return 0;
}
-
VLIB_CLI_COMMAND (mapper_iface_command, static) = {
- .path = "test mapper iface",
- .short_help = "test mapper iface <nsindex> <linux-ifindex> <sw_if_index> [del]",
- .function = mapper_iface_command_fn,
+ .path = "test mapper iface",
+ .short_help =
+ "test mapper iface <nsindex> <linux-ifindex> <sw_if_index> [del]",
+ .function = mapper_iface_command_fn,
};
/* *INDENT-OFF* */
@@ -200,4 +208,3 @@ VLIB_PLUGIN_REGISTER () = {
.description = "netlink",
};
/* *INDENT-ON* */
-